我需要解析以下 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
最佳答案
but the time (second CSV value) is not parsed correctly.
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)
Parse CSV with spaces and semicolons
为了解析 OP 特定格式,以下提出了各种想法。它不是 CSV 解析器(逗号分隔值),因为 OP 不使用逗号。
测试
fopen()
成功if (fp == NULL) { // maybe add message exit(EXIT_FAILURE); }
使用
fgets()
阅读行 @Steve Summitchar 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);
关于c - 用空格和分号解析 CSV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49948548/