2016-08-05 3 views
1

Guten Morgen,Readline.H Geschichte Verwendung in C

Ich versuche, den letzten Befehl zu bekommen, in meinem C-Programm zu schreiben. Gerade jetzt Es ist nur ein Befehl und fügt es in die Geschichte.

#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 %[email protected]%s:", count, p, host); 


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

Ich sehe aus dem Handbuch befindet sich hier https://cnswww.cns.cwru.edu/php/chet/readline/history.html, dass ich nicht in der Lage Informationen aus der Geschichte zu erhalten, ohne Funktion mit:

HIST_ENTRY * history_get (int offset) 

Hat jemand ein Beispiel für Readline- Geschichte haben? Ich habe Probleme, mich um dieses Konzept zu kümmern.

Danke

+1

'sprintf (ps,"% d% s @% s: ", Anzahl, p, Host);' wird undefiniertes Verhalten aufrufen, da Sie dem Zeiger 'ps' keinen Platz zugewiesen haben. – FredK

+0

Wie viel Speicher ist für 'ps' verfügbar? Haben Sie sich 'struct_hist_entry' und' struct_hist_state' (typedeffed zu 'HIST_ENTRY' und' HISTORY_STATE') angesehen? [** 2. Die Programmierung mit GNU History **] (https://cnswww.cns.cwru.edu/php/chet/readline/history.html#SEC6) scheint eine anständige Beschreibung der Benutzung der Bibliothek zu sein. –

Antwort

1

aus den Kommentaren Fortsetzung, Ihre primäre Problem war Ihnen zur Verfügung gestellten nur einen nicht initialisierten Zeiger ohne Speicher für ps zugeordnet. Während Sie dynamisch frei zu ps zuweisen, einfach mit dynamischem Speicher mit ausreichend ist, zB:

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

Neben einen einzigen Eintrag bekommen, die readline- und Geschichte Bibliothek die Möglichkeit, die gesamte Verlaufsliste für eine Sitzung bietet abrufen . Um beispielsweise eine Verlaufssitzung abzurufen, gibt history_list() ein zugeordnetes Array vom Typ HIST_ENTRY ** zurück, das den Verlauf für die Sitzung enthält. Ein kurzes Beispiel für seine Verwendung wäre:

#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 %[email protected]%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 %[email protected]%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 %[email protected]%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; 
} 

Beispiel Verwendung/Output

$ ./bin/readline 
1 [email protected]> command 1 
2 [email protected]> command 2 
3 [email protected]> command 3 
4 [email protected]> quit 

session history for [email protected] 

command 1 
command 2 
command 3 

Blick über Dinge und lassen Sie mich wissen, wenn Sie weitere Fragen haben.

+0

Danke David, es hilft mir, das viel mehr zu verstehen. Mein Endziel ist es, Benutzereingabe 5 zu verwenden und den 5. Befehl zu sehen. Danke, dass Sie mir geholfen haben. Ich sehe wirklich, wie ich das benutze, weil das Handbuch mich nur verwirrte. – user2245682

1

Sie mit int where_history(void) die Zählung des aktuellen (letzten) Eintrag bekommen. Mit Ihrem Beispiel:

#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) " @:\0" angst-allowance 
    //ps = malloc(strlen(p) + strlen(host) +  size_int  + 4   + 1); 
    //sprintf(ps, "%d %[email protected]%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); 
}