【问题标题】:Filtered scanf causing infinite loop过滤后的scanf导致无限循环
【发布时间】:2012-10-05 19:32:52
【问题描述】:

我在一个程序中通过 scanf 过滤输入。 我想要只读数字和大写字母 + 空格。

最近我试图做类似的事情,它卡在一个无限循环中,仍然只打印第一个输入。 我知道fgets(),但我知道这行得通。 我找不到问题出在哪里。 这是简化的情况;我怎么了?

#include <stdio.h>
#include <string.h>

int main()
{
  char str[21];

  do
  {
    scanf("%20[0-9A-Z ]", str);
    printf("%s\n", str);
  } while(strcmp("END", str) != 0);

  return 0;
}

编辑:我忘了说,输入是有效的,对于输入:“HELLO”程序卡住了……scanf 仅在第一次输入时返回 1,对于其他人返回 0。 而且我也试过fflush(stdin),看完之后……

【问题讨论】:

  • 你最好使用getc(stdin) 并检查字符直到它得到20个有效字符。
  • @shiplu.mokadd.im - 是的,我知道这些功能,但我想用 scanf() 来实现它,因为很久以前,我用它做了一些东西..
  • 最好先阅读用户输入,然后通过sscanf()评估其内容

标签: c scanf


【解决方案1】:

您的scanf 只接受数字、大写字母(拉丁字母)和空格,

scanf("%20[0-9A-Z ]", str);

因此,当您输入其他任何内容时,scanf 无法将输入分配给str,并且有问题的输入仍保留在输入缓冲区中。您需要检查扫描是否成功并在失败时清除输入缓冲区。

并且由于特别是换行符不在有效输入标记中,如果输入来自例如,您需要清除输入缓冲区直到下一个换行符。键盘而不是无换行符的输入流。

int c;
do
{
  scanf("%20[0-9A-Z ]", str);
  printf("%s\n", str);
  while((c = getchar()) != '\n' && c != EOF); // clear input buffer
} while(c != EOF && strcmp("END", str) != 0);

【讨论】:

  • 程序如何接收输入?请注意,换行符也将是无效输入。
  • 好的,那肯定是换行符了。
  • Fischer - 是的,你是对的......首先我认为它很糟糕,所以我在阅读后尝试了 fflush(stdin)......它没有用,为什么? :)
  • @hradecek 在输入流上调用 fflush 根据标准是未定义的行为,尽管一些实现说它会丢弃缓冲区中任何已经读取但尚未使用的数据,它即使在那里似乎也不可靠。
  • @igaar str 是正确的,当作为函数参数传递时,数组名称将转换为指向其第一个元素的指针。在所有合理的实现中,&amp;str 也可以工作,因为它指向同一个地址,但它是错误的类型,char (*)[21] 而不是char*
【解决方案2】:

取决于输入 - 但您可以检查 scanf 是否有效 - 它会返回匹配表达式的数量 - 因此在这种情况下应该是 1。 如果它的 0 - 它与输入不匹配,那么它可能会粘在原来的位置。

【讨论】:

    猜你喜欢
    • 2016-06-05
    • 2013-12-20
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 2012-09-27
    • 2012-04-09
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多