以前存储的字符串被 fgets 覆盖

Previously stored strings are overwritten by fgets

我正在从 CSV 文件中读取记录,使用 fgets() 一次读取文件一行,并使用 strtok() 解析每一行中的字段。我遇到 fgets() 覆盖以前写入的字符串以支持新字符串的问题。
这是我的意思的一个例子:

record.csv(这是我正在阅读的文件)

John,18
Johann,29

main.c

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

typedef struct customer {
    char *name;
    int age;
} Customer;

int main(void) 
{
    FILE *csv_data;
    char line[100], *token;
    Customer newData[2];

    csv_data = fopen("record.csv", "r");
    // Index 0 for John's data, index 1 for Johann's data
    int i = 0;

    /* loops until end of file */
    while(fgets(line, 100, csv_data)) {

        /* name field */
        token = strtok(line, ",");
        if (token != NULL) {
            newData[i].name = token;        
        }

        /* age field */
        token = strtok(NULL, ",");
        if (token != NULL) {
            // atoi() converts ascii char to integer
            newData[i].age = atoi(token);
        }
        i++;
    }
    /* print John's records */
    printf("%s\n", newData[0].name);
    printf("%d\n", newData[0].age);

    /* print Johann's records */
    printf("%s\n", newData[1].name);
    printf("%d\n", newData[1].age);

    return 0;
}


当我们编译并执行它时,它会打印出:

Johann
18
Johann 
29
newData[0].name 中的

"John" 在 while 循环的第二次迭代期间被 "Johann" 覆盖。但是请注意,只有字符串会被混淆,整数不会。我怀疑这与 fgets 有关,因为当我将上述源代码修改为仅 运行 fgets 一次时, "John" 的输出是应该的。
也许我误用了 fgets(或者我的假设可能是错误的),但是有人可以给我一些指示,说明为什么每次调用 fgets 都会覆盖字符串吗?

第二次更新:再次非常感谢所有评论者和回答者。很高兴知道那些我不知道的事情。来源现在完美。

做:

newData[i].name = malloc( strlen( token ) + 1 );
strcpy( newData[i].name, token );

或将 name 成员定义为 char name[64];,然后在没有 malloc 的情况下再次定义 strcpy( newData[i].name, token );。 name的64字节可多可少

您复制的不是字符串,而是指向字符串的指针。

一种复制字符串的非常简单的方法,但请注意,这会将字符串的大小限制在 99 个字符。

typedef struct customer {
    char name[100];
    int age;
} Customer;

strcpy(newData[i].name, token);