【问题标题】:How do I read a string until a comma in C89?如何在 C89 中读取字符串直到逗号?
【发布时间】: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 标准很难找到。

标签: c c89 ansi-c


【解决方案1】:

我找到了一种解决方法,将每一行放入缓冲区并首先用空格替换逗号,然后应用%s

#include <stdio.h>

int main() {

    char line[256];    
    char code[10];
    double a,b;

    while(scanf("%s", line) != EOF) {

        /* REPLACE ALL , BY SPACES TO SIMPLIFY SCANF USAGE */
        char *p = line;
        while(*p!='\0') {
            if(*p==',') {
                *p = ' ';
            }
            p++;
        }


        sscanf(line,"%s %lf %lf", code, &a, &b);
        printf("> %s\n", code);
        printf("> %s,%lf,%lf\n", code, a, b);               
    }    

    return 0;   

}

不确定它是否是最优雅的解决方案,但提高了 scanf 部分的可读性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多