如何实现历史功能?

时间:2015-09-18 23:34:25

标签: c shell command-line

我是C编程的新手,目前正在学习这门课程。我在尝试练习以下历史记录功能时遇到了问题。

我能够显示shell命令。但是,当我键入历史记录时,过去的shell命令不会保存到历史记录缓冲区中。

任何人都可以帮我找到我错的地方吗?

以下是我的代码:

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#define BUFSIZE     20  
#define MAX_WORD_IN_LINE 20 

int tokenize(char *str, char **args)
{
    int i, argc = 0;
    char *token;

    token = strtok(str," \t\n");
    for(i=0; token!=NULL;i++)
        {
            args[i] = token;
            printf("args[%d] = %s\n", i, args[i]);
            token = strtok(NULL, " \t\n");
            argc++;
        }
    return argc;
}

void display_strings(char **p)
{
    if (p == NULL) return;
    while(*p != NULL){
        printf("%s\n",*p);
        p++;
    }
}

int history(char *hist[], int current){
    int i = current;
    int hist_num = 1;

    do {
        if (hist[i]) {
            printf("%4d  %s\n", hist_num, hist[i]);
            hist_num++;
        }

        i = (i + 1) % BUFSIZE;

    } while (i != current);

    return 0;
}

int main(void){
    char *args[MAX_WORD_IN_LINE];
    char buffer[BUFSIZE];
    char *hist[BUFSIZE];
    int i,current=0;

    pid_t   pid;
    int argc;

    for(i=0;i<BUFSIZE;i++)
        hist[i]= NULL;

    while(1) {
        memset(args,0,MAX_WORD_IN_LINE);
        printf("osh> ");
        fgets(buffer, BUFSIZE, stdin);
        argc = tokenize(buffer, args);
        //display_strings(args);

        // skip on empty command
        if (argc == 0) continue;

        if (strcmp(args[0],"quit") == 0) break;
        else if (strcmp(args[0], "hello") == 0) printf("Hello there. How are you?\n");
        else if (strcmp(args[0],"history")==0) history(hist,current);
        else {
            pid = fork();
            if (pid == 0) {

                hist[current]=strdup(args[0]);
                current++;

                execvp(args[0], args);
                return 0;
            }

1 个答案:

答案 0 :(得分:0)

您需要复制args[0]hist中保存时指向的字符串。目前,您只是将指针指定给当前args[0],它将被下一个命令覆盖。打印历史记录时,您将重复获取最后一个命令。所以使用:

hist[current] = strdup(args[0]);