Readline.H C 中的历史用法

Readline.H history usage in C

我正在尝试将最后一个命令写入我的 C 程序中。现在它只是接受一个命令并将其添加到历史记录中。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<readline/readline.h>
#include<readline/history.h>

int main(int argc, char **argv){
    char *s;
    char *p = getenv("USER");
    char *host =getenv("HOSTNAME"); 
    int count = 1;
    char *ps;
    sprintf(ps, "%d %s@%s:", count, p, host);


    while (s=readline(ps)){
        add_history(s);
        free(s);
        count++;
        sprintf(ps, "%d %s@%s:", count, p, host);
    }
    return 0;
}

我从此处的手册中看到 https://cnswww.cns.cwru.edu/php/chet/readline/history.html 我无法在不使用函数的情况下从历史记录中获取信息:

HIST_ENTRY * history_get (int offset)

有人有 readline 历史的例子吗?我很难理解这个概念。

谢谢

您可以使用 int where_history(void) 获取当前(最后)条目的计数。以你的例子:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<readline/readline.h>
#include<readline/history.h>
#include <string.h>

// ALL CHECKS OMMITTED!

int main()
{
  char *s;
  char *p = getenv("USER");
  char *host = getenv("HOSTNAME");
  int count = 1;
  char *ps;

  printf("USER: %s\n", p);
  // HOSTNAME does not return anything here, so I skipped it
  printf("HOST: %s\n", host);

  // restricting to 32/64 bit ints for simplicity
  size_t size_int = (sizeof(int) == 4) ? 10 : 20;
  //         env(USER)    env(HOSTN...)   log_10(MAX_INT)  " @:[=10=]"  angst-allowance
  //ps = malloc(strlen(p) + strlen(host) +      size_int       + 4          + 1);
  //sprintf(ps, "%d %s@%s:", count, p, host);
  ps = malloc(strlen(p) + size_int + 4 + 1);
  sprintf(ps, "%d %s:", count, p);

  while ((s = readline(ps)) != NULL) {
    add_history(s);
    free(s);
    count++;
    sprintf(ps, "%d %s:", count, p);
  }

  printf("\nlastline:\n");
  // That's the line you were looking for, I think.
  // int where_history(void) returns the current (that is: last) line
  // HIST_ENTRY *history_get (int) returns the entry data set
  HIST_ENTRY *entry = history_get(where_history());

  printf("%s\n", entry->line);
  free(ps);

  exit(EXIT_SUCCESS);
}

继续评论,您的主要问题是您只提供了一个 未初始化的指针 ,没有为 ps 分配内存。虽然您可以自由地动态分配 ps,但只需使用自动存储就足够了,例如:

char ps[MAXC] = "";  /* where MAXC is a constant of sufficient size */

除了获取单个条目外,readline 和历史库还提供检索会话的整个历史列表的能力。例如,要检索历史会话,history_list () 将 return 分配的类型为 HIST_ENTRY ** 的数组,其中包含会话的历史记录。其使用的一个简短示例是:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<readline/readline.h>
#include<readline/history.h>

enum { MAXC = 128 };

int main (void){

    char ps[MAXC] = "", 
        *p = getenv("USER"),
        *host = getenv("HOSTNAME"),
        *s = NULL; 
    int count = 1;
    sprintf(ps, "%d %s@%s> ", count, p, host);

    using_history();    /* initialize history */

    while ((s = readline(ps))) {
        if (strcmp (s, "quit") == 0) {
            free (s);
            break;
        }
        add_history (s);
        free (s);
        count++;
        sprintf (ps, "%d %s@%s> ", count, p, host);
    }

    /* get the state of your history list (offset, length, size) */
    HISTORY_STATE *myhist = history_get_history_state ();

    /* retrieve the history list */
    HIST_ENTRY **mylist = history_list ();

    printf ("\nsession history for %s@%s\n\n", p, host);
    for (int i = 0; i < myhist->length; i++) { /* output history list */
        printf (" %8s  %s\n", mylist[i]->line, mylist[i]->timestamp);
        free_history_entry (mylist[i]);     /* free allocated entries */
    }
    putchar ('\n');

    free (myhist);  /* free HIST_ENTRY list */
    free (mylist);  /* free HISTORY_STATE   */

    return 0;
}

例子Use/Output

$ ./bin/readline
1 david@alchemy> command 1
2 david@alchemy> command 2
3 david@alchemy> command 3
4 david@alchemy> quit

session history for david@alchemy

 command 1
 command 2
 command 3

检查一下,如果您有任何其他问题,请告诉我。