【问题标题】:Hard-coded string in the format of scanfscanf 格式的硬编码字符串
【发布时间】:2010-11-07 15:48:49
【问题描述】:

我正在尝试匹配格式为“point %d %d”的行。所以我只需要两个这两个整数,然后“点”在格式字符串中被硬编码。据我了解阅读 scanf 的 Linux 手册页,这应该可以正常工作。

下一个代码,我想使用的方式,第一次调用 scanf 有效,但是下一次调用 scanf 返回一个错误代码,并且永远不会从标准输入中获取更多数字(scanf 不会阻止等待来自的更多输入标准输入):

for (;;)
{
    scanf("point %d %d", &x, &y);
    printf("=> point %d %d\n", x, y);
}

这样,一切都按预期工作:

    int x, y;
    char s[10];

    for (;;)
    {
        scanf("%s %d %d", s, &x, &y);
        printf("=> point %d %d\n", x, y);
    }

关于我可能会误解什么的任何建议?

谢谢。

【问题讨论】:

    标签: c scanf


    【解决方案1】:

    我的猜测是你没有给它正确的输入。例如,此输入将不起作用:

    4 5
    

    这应该可行:

    point 4 5
    

    您没有提到错误代码,但可能是说您没有正确遵循格式(即在数字前加上点)。

    【讨论】:

    • 是的,scanf需要匹配“point”才能匹配两个数字。在第二个示例中,%s 匹配空字符串。
    • 好吧,显然我正在输入标准输入行,例如“point 4 5”,因为这是我正在使用的格式。所以,这不是格式的问题,我现在也不想检测输入中的错误。所以在标准输入的第一行(即:“point 4 5”)工作正常,得到 4 和 5。返回码是 2(取两个元素)。在第二行(具有类似正确格式的行)和后续行中,不采用任何内容,scanf 甚至不会阻止等待来自标准输入的更多输入,并且返回码始终为 0(不采用任何元素,因此请注意错误)。
    【解决方案2】:

    stdin 中仍有未使用的数据(例如行尾字符)导致即将进行的扫描因不匹配而停止。在第二个版本中,此行尾数据被%s 使用。

    我建议你先fgets 到一个缓冲区,然后再sscanf 它。并检查您的返回值。

    【讨论】:

    • 好的,你说的解决了我的问题,谢谢。现在我调用 scanf(" point %d %d", &x, &y); “point”之前的blank从stdin中取出了行尾字符,现在它可以工作了。
    【解决方案3】:

    作为一种良好的编程习惯,您应该在接受用户输入之前刷新标准输入。

    【讨论】:

    • 你是怎么做到的,便携的?例如,fflush 保证只在输出流上工作,尽管在某些实现中 fflush 输入流会丢弃任何输入。
    • fflush(stream) 仅用于输出,请阅读此内容 --> "为什么 fflush(stdin) 错误" --> faq.cprogramming.com/cgi-bin/…
    • 我同意在某些编译器中这是未定义的行为。基本上它“应该”清除所有待处理输入的输入流,从而让您清楚地再次开始阅读而没有垃圾输入。这将在 MSVC++ 中工作,因为根据 msdn,他们的 fflush 实现将清除传递给它的任何流。但是,这不适用于所有编译器,因为它不是已定义的行为。这意味着 ANSI 标准委员会没有指定刷新输入流时应该发生什么。
    猜你喜欢
    • 1970-01-01
    • 2012-01-19
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 2016-12-06
    • 1970-01-01
    • 2010-11-10
    相关资源
    最近更新 更多