CSV分析 - 第二个字段返回空值

时间:2016-02-24 10:30:06

标签: c parsing csv

我使用以下代码来解析此CSV

me;val1;val2;val3;val4;val5;
me;val1;val2;val3;val4;val5;
void readcsv()
{
    FILE* stream = fopen("input.csv", "r");

    char line[1024];
    while (fgets(line, 1024, stream))
    {
        char* tmp = strdup(line);
      //  printf("Field 1 would be %s\n", getcsvfield(tmp, 1));
        printf("Field 1 would be %s\n", getcsvfield(tmp, 1));
        printf("Field 2 would be %s\n", getcsvfield(tmp, 2));
        // NOTE strtok clobbers tmp
        free(tmp);
    }
}
//Used for parsing CSV
const char* getcsvfield(char* line, int num)
{
    const char* tok;
    for (tok = strtok(line, ";");
            tok && *tok;
            tok = strtok(NULL, ";\n"))
    {
        if (!--num)
            return tok;
    }
    return NULL;
}

但是我在第二个字段中继续获得NULL值

Output:
Field 1 would be me
Field 2 would be (null)
Field 1 would be me
Field 2 would be (null)

我做错了什么?

1 个答案:

答案 0 :(得分:2)

  

strtok(line,“;”);

strtok修改传递给它的字符串(在本例中为line)。因此,在您第二次致电line时,您也不应该使用相同的getcsvfield(从第一次致电getcsvfield返回),因为在第一次致电getcsvfield之后,{{ 1}}现在有不同的内容。

请注意,这不是函数line中的问题,因为当您第二次将传递给 函数内的getcsvfield时,它知道如何以正确的方式继续修改输入字符串。

manual关于strtok个参数:

  

请注意,此字符串通过分解为较小来修改   字符串(令牌)。

这样的事情应该可以解决问题。这是最“基本”的方法,您也可以尝试其他方法。保留strtok函数,就像您最初在代码中一样,只需在调用者端执行:

getcsvfield

如上所述,每次调用char line[1024]; char buffer[1024]; while (fgets(line, 1024, stream)) { // char* tmp = strdup(line); not necessary in this case strcpy(buffer, line); printf("Field 1 would be %s\n", getcsvfield(buffer, 1)); strcpy(buffer, line); printf("Field 2 would be %s\n", getcsvfield(buffer, 2)); // free(tmp); } ,都会将poitner返回到相同的内存地址 - getcsvfield。对于buffer它可以正常工作(因为在打印时它会显示缓冲区中的内容),但是如果要将每个调用的结果存储到printing以供以后使用,您可能需要复制每次调用getcsvfield到某个不同内存位置的结果。