2017-04-19 155 views
0

我正在尝试编写一个模拟的shell程序,并带有一个打印shell中10个最新条目的历史命令。问题是,当使用history命令时,不是打印输入的行,而是为每个条目打印addToHistory内部数组参数的名称“history”。阵列的打印元素打印数组的名称

这是代码。

void addToHistory(char *line, char **history, int num) { 
    // insert line into first element of history 
    // move elements backward to make room 
    if(num == 0) { 
     history[0] = line; 
    } 
    else if (num > 1 && num < HISTORY_BUFFER) { 
     printf("%d", num); 
     printf("\n"); 
     for(int i = num-1;i > 0;i--) { 
      history[i] = history[i-1]; 
     } 
     history[0] = line; 
    } 
    else if (num > HISTORY_BUFFER) { 
     printf("%d", num); 
     printf("\n"); 
     for(int i = HISTORY_BUFFER-1;i > 0;i--) { 
      history[i] = history[i-1]; 
    } 
     history[0] = line; 
    } 
} 


int main(void) 
{ 
    char *args[MAX_LINE/2 + 1];    /* command line arguments     */ 
    char *history[HISTORY_BUFFER]; 
    char line[64]; 
    int should_run = 1;      /* flag to determine when to exit program */ 
    int num = 0; 
    while (should_run) { 
     printf("osh> "); 
     fflush(stdout); 
     gets(line);       /* read in the command line    */ 
     printf("\n"); 
     parse(line, args);     // function for splitting input into seperate strings; works fine 
     if (strcmp(args[0], "exit") == 0) { /* is it an "exit"?      */ 
      should_run = 0;     /* exit if it is      */ 
     } 
     else if (strcmp(args[0], "history") == 0) { 
      if (num == 0) { 
       printf("No commands in history. Please enter a command and try again\n"); 
      } 
      else if (num < 10) { 
       for(int i = 0;i < num;i++) { 
        printf("%d ", i); 
        printf(history[i]); 
        printf("\n"); 
       } 
      } 
      else { 
       for(int i = 0;i < 10;i++) { 
        printf("%d ", i); 
        printf(history[i]); 
        printf("\n"); 
       } 
      } 
     } 
     /* snip */ 
     else { 
      addToHistory(line, history, num); 
      num++; 
      // executeProcess(args); 
     } 
    } 
} 

经过10项产生的输出是一样的东西

osh> history 
0 history 
1 history 
2 history 
3 history 
4 history 
5 history 
6 history 
7 history 
8 history 
9 history 

其中,“历史”应改为无论是输入到当时的壳。一次输入后,输出简单地是0 history', so the behavior is present in all iterations of addToProcess`。

+2

在任何情况下都不应该使用'gets()'。它在C99中被弃用,并且完全从C11的语言中删除。 –

回答

5

您正在存储一个指向传递给数组中每个元素的addToHistory函数的字符串的指针。由于您在输入新命令时覆盖此字符串,因此当显示历史记录时,每个条目都会显示最后一条命令,在本例中为history

您需要复制字符串以存储到历史数组中。最简单的方法是制作字符串的副本。

而不是仅仅存储阵列中的字符串

history[0] = line; 

使用strdup功能

history[0] = strdup(line); 

注意strdup动态分配内存新的字符串,所以你必须确保你可以调用free删除阵列中的任何条目,否则你将发生内存泄漏。您还需要释放您的程序退出前已分配的任何条目。