[英]Reading values from CSV file into variables
我正在尝试编写一段简单的代码,以从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
很不好,在扫描集结束后需要一个文字s
...谢谢@MichaelPotter
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.