我需要解析以下CSV文件格式:
# cat data.csv
20000530 172700;0.930200;0.930200;0.930200;0.930200;0
20000530 173500;0.930400;0.930500;0.930400;0.930500;0
20000530 173800;0.930400;0.930400;0.930300;0.930300;0
20000530 174300;0.930100;0.930100;0.930000;0.930000;0
值按字符分隔;除了第一个用空格字符分隔的。
我已尝试使用以下代码来解析de CSV,但未正确解析时间(第二个CSV值)。
int read_data() {
char _current_date[16];
char _current_time[16];
float _current_open;
float _current_high;
float _current_low;
float _current_close;
FILE *fp;
fp = fopen("data.csv", "r");
while(fscanf(fp, "%s %[ˆ;]%f;%f;%f;%f;",
_current_date, _current_time,
&_current_open, &_current_high, &_current_low, &_current_close) != EOF) {
printf("%s\n", _current_date);
printf("%s\n", _current_time);
}
fclose(fp);
}
输出是:
20000530
172700;0.930200;0.930200;0.930200;0.930200;0
0.930200;0.930200;0.930200;0
20000530
0.930200;0.930200;0.930200;0
173500;0.930400;0.930500;0.930400;0.930500;0
0.930500;0.930400;0.930500;0
20000530
0.930500;0.930400;0.930500;0
173800;0.930400;0.930400;0.930300;0.930300;0
0.930400;0.930300;0.930300;0
20000530
答案 0 :(得分:2)
但未正确解析时间(第二个CSV值)。
OP的格式不消耗;
,也不消耗最终0
,并且没有正确检查返回值。使用== 6
,而不是!= EOF
。
// ; not consumed
// 0 not consumed
while(fscanf(fp, "%s %[ˆ;]%f;%f;%f;%f;",
_current_date, _current_time, // == 6
&_current_open, &_current_high, &_current_low, &_current_close) != EOF)
使用空格和分号解析CSV
要解析OP特定格式,以下建议各种想法。它不是CSV解析器(逗号分隔值),因为OP不使用逗号。
测试fopen()
成功
if (fp == NULL) {
// maybe add message
exit(EXIT_FAILURE);
}
使用fgets()
阅读行 @Steve Summit
char buf[100]; // suggest 2x expected need
while (fgets(buf, sizeof buf, fp)) {
使用sscanf()
并记录使用"%n"
扫描的线条数量。将文本读入字符串时使用宽度限制。 @user3121023。我在格式中添加了一些空格以允许;
之前的空格。也许使用%15[ˆ; ]
来避免_current_time
int n = 0;
sscanf(buf, "%15s %15[ˆ;] ;%f ;%f ;%f ;%f ;0 %n",
_current_date, _current_time,
&_current_open, &_current_high, &_current_low, &_current_close,
&n);
测试n
现在是否指向buf
if (n == 0 || buf[n] != '\0') {
// Handle failure in some manner
break;
}
// else Success!
使用数据。将<>
之类的标记添加到字符串输出中,以帮助检测意外的前导/尾随空格。
printf("<%s>\n", _current_date);
printf("<%s>\n", _current_time);
}
清理
fclose(fp);