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

时间:2009-12-24 18:06:42

标签: 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");
}

出于某种原因,scanf捕获了char和换行后的内容,因此它继续对输入执行某些操作,然后还打印“请仅输入'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'!
$

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

4 个答案:

答案 0 :(得分:9)

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

scanf(" %c", &choice);

你还需要使用&amp; choice,而不是选择!

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

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:3)

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

答案 3 :(得分:0)

首先,我会保持简短。因为没有足够的分数来提交评论 如果我们可以看到o / p的数量是(一个+不是字符) 这是因为我们在输入字符'\ 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
  

EDITED   由于分数不足,我可以将其作为评论发布。这是上述答案的解决方法