繁体   English   中英

C - 尝试使用 scanf / getchar 从标准输入(并且失败)读取单个字符

[英]C - trying to read a single char from stdin (and failing) w/ scanf / getchar

作为家庭作业的一部分,我试图从标准输入读取单个字符,并根据它采取行动:

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'!” 线。 如果我在 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,也会发生同样的事情。 我错过了什么? 谢谢。

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

scanf(" %c", &choice);

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

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

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

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

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

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

首先我会保持简短。因为点数不足,无法提交评论如果我们可以看到o/p的数量是(一个+字符的数量)这是因为我们在输入字符后按回车键'\\n ' 不可打印的字符也会在您的字符串之后添加。

$ ./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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM