user2245682 user2245682 - 2 years ago 284
C Question

Readline.H history usage in C

Good Morning,

I'm trying to get the last command to write inside of my C program. Right now It is just taking a command and adding it to history.

#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;
}


I see from the manual located here https://cnswww.cns.cwru.edu/php/chet/readline/history.html That I'm unable to get information from history without using Function:

HIST_ENTRY * history_get (int offset)


Does anyone have an example of readline history? I'm having trouble wrapping my mind around this concept.

Thank you

Answer Source

Continuing from the comments, your primary issue was you provided only an uninitialized pointer with no memory allocated for ps. While you are free to dynamically allocate ps, simply using automatic storage is sufficient, e.g.:

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

In addition to getting a single entry, the readline and history library provides the ability to retrieve the entire history list for a session. For example to retrieve a history session, history_list () will return an allocated array of type HIST_ENTRY ** containing the history for the session. A short example of its use would be:

#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;
}

Example Use/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

Look things over and let me know if you have any further questions.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download