C语言 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 %sn", getcsvfield(tmp, 1));
        printf("Field 1 would be %sn", getcsvfield(tmp, 1));
        printf("Field 2 would be %sn", 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)

我做错了什么?

strtok(line, ";");

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

请注意,这不是函数getcsvfield的问题,因为当您第二次将 NULL 传递给函数内部的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 %sn", getcsvfield(buffer, 1));
    strcpy(buffer, line);
    printf("Field 2 would be %sn", getcsvfield(buffer, 2));
    // free(tmp);
}

如上所示,每次调用 getcsvfield 时,都会将 poitner 返回到相同的内存地址 - buffer 。对于printing它工作正常(因为在打印时它显示了缓冲区中的内容),但是如果要将每次调用的结果存储到getcsvfield以供以后使用,则可能需要每次将每次调用getcsvfield的结果复制到某个不同的内存位置。

相关内容

最新更新