将CSV文件中的值读入变量

我正在尝试编写一段简单的代码来读取CSV文件中的值,最多包含100个条目到一个结构数组中。

CSV文件的一行示例:

1,先生,詹姆斯,奎格利,主任,200000,0

我使用以下代码读取值,但是当我打印出值时,它们是不正确的

for(i = 0; i < 3; i++) /*just assuming number of entries here to demonstrate problem*/ { fscanf(f, "%d,%s,%s,%s,%s,%d,%d", &inArray[i].ID, inArray[i].salutation, inArray[i].firstName, inArray[i].surName, inArray[i].position, &inArray[i].sal, &inArray[i].deleted); } 

然后当我打印出第一个名字时,这些值都被分配给第一个名字:

 for(j = 0; j < 3; j++) /* test by printing values*/ { printf("Employee name is %s\n", inArray[j].firstName); } 

以这种方式给出ames,Quigley,Director,200000,0等等。 我确定这是我如何格式化fscanf线但我不能让它工作。

这是我正在阅读的结构:

 typedef struct Employee { int ID; char salutation[4]; char firstName[21]; char surName[31]; char position[16]; int sal; int deleted; } Employee; 

这是因为字符串%s可以包含逗号,因此它会被扫描到第一个字符串中。 scanf()格式化说明符中没有“预见”, %s后面跟着格式规范字符串中的逗号这一事实没有任何意义。

使用字符组( 在 [ ]中搜索手册 。

 const int got = fscanf(f, "%d,%[^,],%[^,],%[^,],%[^,],%d,%d", &inArray[i].ID, inArray[i].salutation, inArray[i].firstName, inArray[i].surName, inArray[i].position, &inArray[i].sal, &inArray[i].deleted); 

并学会检查返回值 ,因为I / O调用可能会失败! 除非got 7,否则不要依赖有效数据。

为了让你的程序读取整个文件(多个记录,即行),我建议使用fgets()将整行加载到(大)固定大小的缓冲区中,然后在该缓冲区上使用sscanf()来解析列值。 这更容易,并且将确保您确实扫描单独的行,在循环中调用fscanf()不会,因为对于fscanf() ,换行只是空格。

不妨发表我的评论作为答案:

%s默认读取一个完整的单词。

它找到%d ,整数部分,然后是,然后它必须读取一个字符串。 ,在一个单词中被认为是有效的(它不是空格),所以它一直读到行的末尾(直到那时才有空格),直到第一个逗号才开始……其余的都是空的。 (从这个回答)

您必须通过指定正则表达式来更改分隔符:

 fscanf(f, "%d,%[^,],%[^,],%[^,],%[^,],%d,%d", &inArray[i].ID, inArray[i].salutation, inArray[i].firstName, inArray[i].surName, inArray[i].position, &inArray[i].sal, &inArray[i].deleted); 

而不是%s ,使用%[^,] ,这意味着“抓住所有字符,并在找到时停止”。

编辑

%[^,]s很糟糕,在扫描集结束后需要一个文字…谢谢@MichaelPotter

(从更改scanf()分隔符和从CSV文件读取值到变量 )