我正在尝试从每行 1 个单词和 20 行的列表中读取,然后将每个单词添加到链表的末尾。我的问题是,当我在最后打印出链表时,它会打印文件中的最后一个单词 20 次,而不是每个单词打印一次。我已经为此工作了几个小时,但无法弄清楚我做错了什么。
在我的主要我有
while (!feof(input)) {
fscanf(input, "%s", currentName);
head = insert(head, currentName);
}
print(head);
delete(head);
插入函数
node* insert(node* head, char* name) {
node *temp = NULL;
if (head == NULL) {
head = create_node(name);
}
else {
temp = head;
while(temp->next != NULL){
temp = temp->next;
}
temp->next = create_node(name);
}
return head;
}
创建函数
node* create_node(char* name) {
node *newNode;
newNode = malloc(sizeof(node));
if(newNode == NULL) {
printf("Failed to create node");
}
newNode->name = name;
newNode->next = NULL;
return newNode;
}
打印和删除
void print(node* head){
while (head != NULL) {
printf("%s -> ", head->name);
head = head->next;
}
printf("NULL\n");
}
void delete(node* head) {
node *temp = NULL;
while(head != NULL) {
temp = head;
head = head->next;
free(temp);
}
}
最佳答案
对于每次插入,您都将同一缓冲区的地址保存回 main()
中。每个节点只是保存 currentName
的基址,其内容随着每个输入的处理而改变。因此,您有一个包含 name
指针的结构链表,其中每个指针都指向相同的缓冲区 (currentName
)。因此,最后一个将是您唯一看到的。
需要在create_node
中为name动态分配空间。下面使用 POSIX 函数 strdup()
来执行此操作,但如果您愿意,您可以完全自由地使用 strlen/malloc
组合。
node* create_node(char* name)
{
node *newNode;
newNode = malloc(sizeof(node));
if(newNode == NULL)
printf("Failed to create node");
newNode->name = strdup(name);
newNode->next = NULL;
return newNode;
}
不要忘记在清理链接列表时为 free()
每个节点名称以避免内存泄漏。
void delete(node* head)
{
node *temp = NULL;
while(head != NULL)
{
temp = head;
head = head->next;
free(temp->name);
free(temp);
}
}
无关:您用于加载内容的 while 循环条件是错误的。 Read this answer to see why
关于C链表-在末尾插入节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21565023/