我使用以下代码来解析此 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
的结果复制到某个不同的内存位置。