C:将文本文件中的数据添加到单个链接列表中

时间:2014-09-11 19:28:53

标签: c file singly-linked-list

我最近开始学习C编程。我有一些java经验所以我知道我的代码方式,我喜欢思考.. 我正在做的这件小事就是杀了我。 我正在尝试制作一个程序来读取文本文件中的行 - >将其存储在单链表中 - >打印出单链表 到目前为止,这是我的代码:

typedef struct node {
    char *data;
    struct node *next;
} node;

node *start = NULL;
node *current;


void add(char *line) {

    node *temp = malloc(sizeof(node));
    // This line under I believe where my problem is...
    temp->data = line;
    temp->next = NULL;
    current = start;

    if(start == NULL) {
        start = temp;
    } else {
        while(current->next != NULL) {
            current = current->next;
        }
        current->next = temp;
    }
}

这是我的函数,用于读取文件并将字符发送到添加功能

void readfile(char *filename) {
    FILE *file = fopen(filename, "r");

    if(file == NULL) {
        exit(1);
    }

    char buffer[512];

    while(fgets(buffer, sizeof(buffer), file) != NULL) {
        // I've tried to just send i.e: "abc" to the add function
        // which makes the program work.
        // like: add("abc");
        // my display method prints out abc, but when I'm sending buffer
        // it prints out nothing
        // Thing is, I've spent way to much time trying to figure out what
        // I'm doing wrong here...
        add(buffer);
    }

    fclose(file);
}

我确信这是一个相当简单的问题,但我花了太多时间来解决这个问题。 如果还有其他什么东西可以看起来/可能更好,我也很欣赏它的反馈:)

2 个答案:

答案 0 :(得分:4)

尝试:

temp->data = strdup(line);

dup许可(复制)什么行指向。

否则每一行都指向buffer,每一行都会被新行覆盖。

答案 1 :(得分:4)

您需要为字符串分配内存 - 每行都被读入buf,因此您需要将其复制出来,否则将被后续行覆盖。我建议使用两种方法中的一种,第一种方法是最简单的方法,但第二种方法更好,因为你只需要为每个对象做一次free()。​​

第一个只是对add()函数的一次更改:

temp->data = malloc(strlen(line)+1);
strcpy(temp->data, line);

现在,当你想释放链表中的一个对象时,你必须首先调用free()数据然后free()对象本身。

但是,您可以稍微更改结构,然后您可以一次性分配整个对象:

typedef struct node {
  struct node *next;
  char data[0];
} node;

然后你的add()函数看起来像这样:

void add(char *line) {

  node *temp = malloc(sizeof(node)+strlen(line)+1);
  strcpy(temp->data, line);
  temp->next = NULL;
  current = start;

  if(start == NULL) {
    start = temp;
  } else {
    while(current->next != NULL) {
      current = current->next;
    }
    current->next = temp;
  }
}

请注意,您当然应该在生产代码中的每个malloc()之后执行错误检查。当你完成一个对象时,一个free()足以释放整个结构。

编辑:"数组长度0" feature是一个GCC特定的扩展,正如@crashmstr在评论中所指出的那样。如果使用数组长度为1,则它应该适用于任何编译器:

typedef struct node {
  struct node *next;
  char data[1];
} node;

由于在这种情况下已经分配了一个额外的字节,因此add()函数中的malloc()调用将变为:

  node *temp = malloc(sizeof(node)+strlen(line)+1-1);

(当然+ 1-1可以省略,但它只是为了表明我们仍然需要空终止器,但是sizeof中已经包含了一个额外的字节)。