将fscanf中的字符串附加到C中的链表

将fscanf中的字符串附加到C中的链表,c,string,data-structures,linked-list,C,String,Data Structures,Linked List,我想读一个文件,把每个单词都放在一个链表中。当我读取该文件时,链表的节点数很好,但所有节点都等于最后一个单词 例如,如果我的文本文件是: Hello good sir 我的链接列表如下所示: [sir,sir,sir] 应该是这样的: [Hello, good, sir] 我的主要工作 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h>

我想读一个文件,把每个单词都放在一个链表中。当我读取该文件时,链表的节点数很好,但所有节点都等于最后一个单词

例如,如果我的文本文件是:

Hello good sir
我的链接列表如下所示:

[sir,sir,sir]
应该是这样的:

[Hello, good, sir]
我的主要工作

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

typedef struct NodeTag {
  char *data;
  struct NodeTag *next;
} Node;

Node *Node_create();

typedef struct ListTag {
  struct NodeTag *first;
} List;

List *List_create();
void List_append(List *list, char *str);
void List_print(List *list);

int main(void) {
  char word[100];
  FILE *file = fopen("file.txt", "r");

  if(file == NULL) {
    printf("error in opening file\n");
    return 1;
  }

  List *l = List_create();

  while(fscanf(file, "%s", word) == 1){
    List_append(l, word);
  }
  return 0;
}
如果我这样做,它会正常工作。所以我想我只附加单词的指针,所以它一次又一次地指向同一个地方

    List_append(l, "test1");
    List_append(l, "test2");
输出:

   [test1, test2]

请注意,在
main
中,有一个缓冲区存储字符串:

char word[100];
word
作为参数传递给
List\u append
方法,在此过程中进行写入

node->data = str;
这意味着所有节点都指向其字符串的
main
中的
word
缓冲区,因此所有节点都将显示相同的字符串

要解决这个问题,您需要在某个地方复制缓冲区。我建议你这样做:

node->data = strdup(str);
代码中可能还有其他问题,但这肯定是在继续之前需要解决的问题。尝试更新此文件,看看它是否解决了您的问题。正如@Sean Bright所指出的,在执行追加时,您似乎也覆盖了错误的字符串指针,因此您可能还需要解决这个问题


希望这有帮助

列表\u append
中,您正在执行以下操作:

node->data = str;
这将保存指向作为
str
传入的数据的指针。您在main中调用
List\u append(l,word)
,这意味着您每次都要传递相同的内存块,因此每个列表成员都指向相同的内存块

您需要在
列表\u append
中执行此操作:

node->data = strdup(str);

这会将字符串复制到新分配的缓冲区中。清理时请确保
释放它。

节点->数据=str需要一个字符串副本-->
节点->数据=strdup(str)
node->data = strdup(str);