2015-09-18 180 views
-2

我是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; 
      } 
+0

你的代码在'main()'函数的中间结束。 – Barmar

+0

最重要的是,*你*可以提供帮助。坚持在几个打印语句中追踪执行路径并在关键处理点打印出变量。最重要的是,从打印开始,跟踪如何将行添加到历史记录缓冲区。 – Prune

回答

0

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

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

感谢让我知道这一点。我将添加上述步骤 – bhaski