2017-04-19 158 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刪除陣列中的任何條目,否則你將發生內存泄漏。您還需要釋放您的程序退出前已分配的任何條目。