2013-12-14 82 views
1

我正在研究一個基本的unix shell,我想添加的功能之一是一個'history'命令,它將用戶嘗試的所有命令那屆會議。我的研究表明實現此目的的最佳方式是使用鏈接列表。鏈接列表實現將命令歷史記錄存儲在我的shell中

這是我的實現,無論我輸入什麼命令,它只存儲「歷史」命令。我只在主殼程序中包含了我認爲有必要的內容。

這裏是輸出

//output 
mish> echo Hello World 
Hello World 
mish> date 
Sat Dec 14 16:35:31 EST 2013 
mish> history 
============ Command History ============ 
[1] history 
[2] history 
[3] history 
========================================= 
mish> 

下面是主殼

//main.c 
List *historyList = malloc (sizeof(List)); 
//get command 
addHistory(historyList, command); 

//do other shell stuff (parsing, etc.) 
if (userInput is "history) 
    printHistory; 

這裏是history.c

//history.c 
typedef struct History{ 
    char *command; 
    struct History *next; 
}History; 

typedef struct List{ 
    unsigned int count; 
    History *top; 
}List; 

void addHistory(List *list, char *cmd){ 
    History *h = (History*) malloc(sizeof(History)); 
    h->command = cmd; 

    if (isHistoryEmpty(list)){ 
     h->next = NULL; 
     list->top = h; 
    } 
    else{ 
     h->next = list->top; 
     list->top = h; 
    } 
    list->count++; 
} 

bool isHistoryEmpty(List *list){ 
    if (list->count == 0){ 
     return true; 
    } 
    return false; 
} 

void clearHistory(List *list){ 
    while (!isHistoryEmpty(list)){ 
     History *temp = list->top; 
     list->count--; 
     list->top = list->top->next; 
     free(temp); 
    } 
    free(list); 
} 

void printHistory(List *list){ 
    int i = 1; 
    printf("Command History\n"); 
    while (!list->top == NULL){ //this line causes a warning on compilation (comparison between pointer and integer) 
     History *temp = list->top; 
     printf("[%d] %s \n", i, temp->command); 
     list->top = list->top->next; 
     i++; 
    } 
}               19,2-5  Top 

回答

2

您不作command副本,所以所有的歷史記錄項共享command緩衝區。當用戶輸入命令時,它會被讀入唯一的緩衝區,並且所有的歷史項目都會改變爲最新的命令。

History *h = (History*) malloc(sizeof(History)); 
h->command = (char*) malloc(sizeof(char) * (strlen(cmd) + 1)); 
strcpy(h->command, cmd); 

當列表被清除時,副本將不得不被釋放。

一些更多的bug:

  • !==更高的優先級,所以無論使用!=或使用括號:!(list->top == NULL)

  • 當通過列表迭代不得修改list->top。相反,請將temp的聲明和初始化移至循環外,並使用temp代替list->top

+0

湯姆,謝謝,您的修復解決了這個問題。我發現了另一個與我的printHistory函數有關的bug,一旦它被打印,它就會破壞歷史! –

+0

非常棒的建議湯姆,非常感謝。乾杯! –

+0

不客氣。不要忘了釋放命令;) – tom

相關問題