【问题标题】:C - trying to read a single char from stdin (and failing) w/ scanf / getcharC - 尝试使用 scanf / getchar 从标准输入读取单个字符(并且失败)
【发布时间】:2010-12-29 21:03:28
【问题描述】:

作为家庭作业的一部分,我正在尝试从标准输入读取单个字符,并按照它行事:

char choice;

while (1) {
    printf("please enter [y]es, [n]o or [m]aybe: ");
    scanf("%c", choice);
    fflush(stdin);
    // validate input
    if (choice == 'y' || choice == 'n' || choice == 'm') {
        break;
    } else {
      printf("Please enter only \'y\', \'n\' or \'m\'!\n");
    }
}
// do something with the input
if (choice == 'y') {
    printf("you selected yes!\n");
}

由于某种原因,scanf 会同时捕获字符和换行符,因此它会继续对输入进行处理,然后还会打印“请仅输入 'y'、'n' 或 'm'!”线。如果我在标准输入上输入几个字符,它将为所有这些字符打印该行,同时也为第一个字符正确执行。因此,例如:

$ ./run
please enter [y]es, [n]o or [m]aybe: y<return>
you selected yes!
Please enter only 'y', 'n' or 'm'!
$ ./run
please enter [y]es, [n]o or [m]aybe: yes<return>
you selected yes!
Please enter only 'y', 'n' or 'm'!
Please enter only 'y', 'n' or 'm'!
Please enter only 'y', 'n' or 'm'!
$

如果我使用 getchar,也会发生同样的事情。我错过了什么?谢谢。

【问题讨论】:

    标签: c scanf


    【解决方案1】:

    scanf("%c 之间需要一个空格才能正常工作:

    scanf(" %c", &choice);
    

    而且你还需要使用&choice,而不是choice!

    编辑:当您使用它时,您可能想查看 do while() 的那个循环(除非教授特别说要使用 break) - do while 在验证用户输入时效果很好!

    【讨论】:

    • 直到你得到意想不到的输入;例如,尝试输入“y x z”。
    • 哈哈,真是个传奇!
    【解决方案2】:

    fflush() 不是 ISO C 为输入流定义的。它在 Microsoft 的 C 运行时库中定义,但不可移植。

    虽然“%c 之前的空格”解决方案可能在用户输入预期数据时起作用,但它会在很多方面失败;例如,尝试输入“y n y n”。控制台输入是面向行的;你最好的选择是确保你丢弃整条线:

    scanf( "%c", &choice ) ;
    while( choice != '\n' && getchar() != '\n' ) /* do nothing*/ ;
    

    【讨论】:

      【解决方案3】:

      更好的是,使用 fgetc()。 scanf() 应该永远是最后的手段。

      【讨论】:

        【解决方案4】:

        首先我会保持简短。由于积分不足,无法提交评论 如果我们可以看到 o/p 的数量是 (one + the no of charcter) 这是因为当我们在输入字符 '\n' 后按 Enter 键时,该字符也会被添加到您的字符串之后。

        $ ./run
        please enter [y]es, [n]o or [m]aybe: y<return>
        you selected yes!
        Please enter only 'y', 'n' or 'm'!  -----------> it is due to reading of the '\n' by scanf
        

        已编辑 由于积分不足,我可以将此作为评论发布。这是上述答案的解决方法

        【讨论】:

        • 这是解决问题的方法,不是吗?所以这是对问题的评论(不是答案)。
        • 没有足够的积分我想要但不知道我会因此而被否决。
        猜你喜欢
        • 2011-01-31
        • 1970-01-01
        • 2018-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多