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

时间:2017-06-27 22:14:41

标签: c csv fgets strtok

我使用fgets()从CSV文件中读取记录,一次读取一行文件,然后使用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

&#34;约翰&#34;在newData[0].name被{&#34; Johann&#34;在while循环的第二次迭代期间。但请注意,只有字符串混淆,而不是整数。我怀疑这与fgets有关,因为当我将上述源修改为仅运行fgets一次时,&#34; John&#34;的输出。是应该的。
也许我误用了fgets(或者我的假设是错误的),但是有人可以给我一些关于为什么在每次调用fgets时都会覆盖字符串的指针?

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

2 个答案:

答案 0 :(得分:1)

执行:

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

或将name成员定义为char name[64];,然后再将strcpy( newData[i].name, token );定义为malloc。名称的64个字节可以更多或更少。

答案 1 :(得分:1)

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

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

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

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