【发布时间】:2021-08-19 03:35:57
【问题描述】:
我正在尝试使用scanf 读取c89 中的CSV 文件:
FOO,2,3
BAR,5,4
...
这是我尝试过的:
#include <stdio.h>
int main() {
char code[10];
double a,b;
while( scanf("%s,%lf,%lf", code, &a, &b)!=EOF ) {
printf("> %s\n", code);
printf("> %s,%lf,%lf\n", code, a, b);
}
return 0;
}
这是我得到的输出:
$ ./a.out
A,2,3
> A,2,3
> A,2,3,0.000000,0.000000
B,5,4
> B,5,4
> B,5,4,0.000000,0.000000
$
这是我对上述代码的预期输出:
$ ./a.out
A,2,3
> A
> A,2.000000,3.000000
B,5,4
> B
> B,5.000000,4.000000
$
编辑
根据提供的评论,我已经尝试过:
#include <stdio.h>
int main() {
char code[10];
double a,b;
while( scanf("%9[^,],%lf,%lf", code, &a, &b)!=EOF ) {
printf("> %s\n", code);
printf("> %s,%lf,%lf\n", code, a, b);
}
return 0;
}
我得到:
$ cat > test.txt
A,2,3
B,4,5
C,5,6
$ cat test.txt | ./a.out
> A
> A,2.000000,3.000000
>
B
>
B,4.000000,5.000000
>
C
>
C,5.000000,6.000000
>
>
,5.000000,6.000000
$
显然第一条记录已正确处理,但后续记录未正确处理。
我还有关于9 的作用以及整个%9[^,] 是否是c89 的一部分的问题。
【问题讨论】:
-
你试过用
%9[^,]替换你的scanf阅读器的%s吗? -
您可能想要测试
scanf的返回值与 3 的对比,以防您读取了部分元素但不是全部。 -
您的“不是后续的”看起来像是在前一行的末尾有剩余的空格。您可以试试
" %9[^,],即在开头引号和百分号之间留一个空格。 -
而且,
9是为了确保您的读取操作不会爆炸地通过声明的code(10) 缓冲区大小并随后进入未定义行为的领域。 -
在这种情况下,
scanf将返回四个东西,[EOF, 0, 1, 2, 3]; UB 如果[0, 1, 2],至少应将!= EOF替换为== 3。 @thebusybee C90 标准很难找到。