在C中从fscanf向链表添加一个字符串



我想读取一个文件,并将每个单词放在一个链表中。当我读取文件时,链表有足够的节点数,但是所有的节点都等于最后一个单词。

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

Hello good sir

我的链表看起来像这样:

[sir,sir,sir]

应该是这样的:

[Hello, good, sir]
我的c

#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 filen");
    return 1;
  }
  List *l = List_create();
  while(fscanf(file, "%s", word) == 1){
    List_append(l, word);
  }
  return 0;
}
以下是我的函数。我删除了destroy和free函数,使它更清晰。
Node *Node_create() {
  Node *node = malloc(sizeof(Node));
  assert(node != NULL);
  node->data = "";
  node->next = NULL;
  return node;
}
List *List_create() {
  List *list = malloc(sizeof(List));
  assert(list != NULL);
  Node *node = Node_create();
  list->first = node;
  return list;
}
void List_append(List *list, char *str) {
  assert(list != NULL);
  assert(str != NULL);
  Node *node = list->first;
  while (node->next != NULL) {
  node = node->next;
  }
  node->data = str;
  node->next = Node_create();
}
void List_print(List *list) {
  assert(list != NULL);
  printf("[");
  Node *node = list->first;
  while (node->next != NULL) {
    printf("%s", node->data);
    node = node->next;
    if (node->next != NULL) {
      printf(", ");
    }
  }
  printf("]n");
}

如果我这样做,它将正常工作。所以我猜我只附加了word的指针它就会一次又一次地指向同一个地方?

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

   [test1, test2]

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

char word[100];

word作为参数传递给List_append方法,在此过程中写入

node->data = str;

这意味着所有节点都指向main中的word缓冲区以获取它们的字符串,因此它们都将显示相同的字符串。

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

node->data = strdup(str);

代码中可能还有其他问题,但这肯定是在继续之前需要解决的问题。尝试更新这个,看看它是否解决了您的问题。正如@Sean Bright指出的那样,当你执行追加操作时,似乎你也覆盖了错误的字符串指针,所以你可能也需要修复这个问题。

希望这对你有帮助!

List_append内部,您要这样做:

node->data = str;

保存了一个指向传入的str数据的指针。在main中调用List_append(l, word),意味着每次传递给它的都是同一块内存,所以每个列表成员都指向同一块内存。

您需要在List_append:

中这样做
node->data = strdup(str);

将字符串复制到新分配的缓冲区中。当你清理的时候一定要把它free

相关内容

  • 没有找到相关文章

最新更新