C - 尝试从stdin读取单个char(并且失败)w/scanf/getchar

sa1*_*125 5 c scanf

作为家庭作业的一部分,我试图从stdin读取一个字符,并根据它行事:

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");
}
Run Code Online (Sandbox Code Playgroud)

由于某种原因,scanf捕获了char和line-feed之后,因此它继续对输入执行某些操作,然后还打印"请仅输入'y','n'或'm'!" 线.如果我在stdin上输入几个字符,它将为所有字符打印该行,同时也为第一个字符正确执行.所以,例如:

$ ./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'!
$
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*tte 9

你需要一个空间scanf("%c它之间的正确工作:

scanf(" %c", &choice);
Run Code Online (Sandbox Code Playgroud)

你还需要使用和选择,而不是选择!

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


Cli*_*ord 5

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

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

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