我正在为我的系统编程类编写Linux的shell。在编写我的命令历史记录部分的链表时,我遇到了一个非常奇怪的情况,我真的不确定我做错了什么。
现在我将程序设置为接受char数组作为输入,并将数据添加到链表末尾的节点中,然后将该节点设置为列表的尾部。然后我让程序从尾部到头部打印列表。我应该看到的是我输入的历史,顺序相反。我所看到的是,我最后输入的内容似乎是覆盖了所有先前节点中的数据。
例如:我输入1,我打印1,然后输入2,我得到两个2打印回来而不是2然后是1.有谁知道发生了什么?我的代码如下。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INPUT_BUFFER 255
typedef struct commandHistoryNode commandHistoryNode;
struct commandHistoryNode{
commandHistoryNode *previous;
commandHistoryNode *next;
char *commandLine;
};
commandHistoryNode* AddCommandToLinkedList(commandHistoryNode *, char *);
void PrintLinkedList();
void ExecuteCommand(char *);
int main(int argc, char **argv){
char *cmdString;
cmdString = calloc(INPUT_BUFFER, sizeof(char));
char *PS1 = "$";
commandHistoryNode *currentNode = NULL;
while(1)
{
printf(PS1);
fgets(cmdString, INPUT_BUFFER, stdin);
//currentNode is the tail of the LinkedList
currentNode = AddCommandToLinkedList(currentNode, cmdString);
PrintLinkedList(currentNode);
}
}
void ExecuteCommand(char *passedCommand){
return;
}
commandHistoryNode*
AddCommandToLinkedList(commandHistoryNode *passedNode, char *passedCommand){
commandHistoryNode *tailNode = malloc(sizeof(commandHistoryNode));
tailNode->commandLine = passedCommand;
if(passedNode == NULL)
{
//passedNode is the head of the list
return tailNode;
}
else
{
while(passedNode->next!=NULL)
{
//if passedNode isn't the tail (and it should be), iterate through the list
passedNode = passedNode->next;
}
//set tempNode to the next node for the passedNode
passedNode->next = tailNode;
//set the previous node for tempNode to point to the passedNode
//as it is the new tail.
tailNode->previous = passedNode;
}
//return new tailNode
return tailNode;
}
void PrintLinkedList(commandHistoryNode *tailNode){
while(tailNode != NULL)
{
printf("command is: %s\n", tailNode->commandLine);
//iterate backwards from the tail to the head
tailNode = tailNode->previous;
}
}
答案 0 :(得分:2)
每次调用AddCommandToLinkedList时,都会继续使用相同的cmdString。所以每个节点都指向相同的字符缓冲区。因此,每次有新命令时,都会使用该命令覆盖唯一的字符缓冲区,并且每个节点都指向该命令。您需要为每个命令分配一个cmdString,而不是重新使用它。
答案 1 :(得分:0)
如果passNode为!= NULL
,则再次检查您返回的内容。