C 跳过操作

4

我正在尝试制作一个基本的C控制台应用程序计算器。但是当我执行它时,第二个scanf命令被跳过,第三个则被执行。这是一个问题,因为在这里我需要获取用户的操作符号 +、-、*或/。我该如何阻止这种情况发生?

float num1;
char sign;
float num2;
float total;
printf("~~~ Calculator ~~~\n");
printf("Please enter the first number: ");
scanf("%f", &num1);//Get value of num1 from user

printf("\nNow please enter the operation , either +, -, *, or / : ");
scanf("%c", &sign);//Get value of sign from user 

printf("\n\nFinaly enter the second number: ");
scanf("%f", &num2);

编辑:实际上,经过尝试各种建议后,似乎在%c之前加上一个空格是正确的方式,也是最简洁的方式来解决问题。感谢您的帮助。


第二个scanf没有被跳过。想想这个:第一个scanf扫描的是“%f”,它不包括你输入的换行符。第二个scanf扫描的是“%c”,当然应该读取换行符。对于这种输入,我建议使用fgets + sscanf代替。 - Brandin
4
这是一个重复的问题,不知道有多少个。问题在于找到一个好的标记为重复的问题。我在“相关问题”列表中看到了5个可能的候选项,但是它们都不像是一个好的选择。 - Jonathan Leffler
4个回答

2
在%c前加一个空格,这样它就会消耗掉换行符,像这样:
scanf(" %c", &sign);//Get value of sign from user

当我这样做时,控制台一直在等待输入,没有输出我希望的下一行文本。 - user3065549
@ Mikey 这个应该工作的。你是期望这个 scanf(" %c", &sign) 一旦输入了一个像 '+' 的字符,就立即返回吗? - chux - Reinstate Monica

1
当你按下回车键后,第一个 scanf 函数会读取实际数字并留下一个 \n。后者会在下一个 scanf 函数中被读取。
scanf("%f\n", &order)

为了消耗你输入的 \n,请执行此操作。


正如@JonathanLeffler所提到的,更好的方法是在下一行中使用" %c"(注意空格)以便消耗换行符。

不是“跳过换行符”,而是“将换行符留在输入中,以便下一个操作读取”。另外(我之前应该说过),最好的修复方法可能是使用“%c”来读取下一个非空格字符。在格式字符串的末尾放置“\n”对于用户进行输入非常恶心,因为输入不会结束,直到用户键入一个不是空格的字符。 - Jonathan Leffler
@JonathanLeffler 谢谢。已编辑。 - Maroun

1
程序要求输入第一个数字后,您输入一个数字,然后按回车键。这样,数字就存储在变量num1中。但是,换行符'\n'仍然在缓冲区中,您需要在执行第二个scanf之前清除缓冲区。否则,signe变量将接受'\n'作为输入,因为它是一个字符,它不会提示输入。
在请求输入char之前,应始终清除缓冲区。
int c;
do {
    c = getchar(); // clearing the buffer
} while (c!='\n' && c!=EOF);
printf("\nNow please enter the operation , either +, -, *, or / : ");
scanf("%c", &sign);//Get value of sign from user

现在应该可以工作了。

stdin关闭并且getchar()永远返回EOF时,使用while(getchar()!='\n');会出现问题。这样就无法离开循环。 - chux - Reinstate Monica
非常好,除了 c 需要是 int - chux - Reinstate Monica

-2
其实,这是因为程序的 stdin 流中仍然存在值。 一个简单的解决方法是使用:

修复:不要使用 -> fflush(stdin);

通过使用 scanf("%f\n") 消耗换行符...

在第二次调用 scanf 之前...

最好!


https://dev59.com/5HA85IYBdhLWcg3wBOzh - Mat
4
fflush (...) 对于输入流(例如 stdin)是未定义的。 - Andon M. Coleman
谢谢,以前从没注意到这个。 - Daniel Trugman
清理混乱是一项艰苦的工作。Windows和Linux都定义了fflush(stdin)的行为(奇迹般地),它执行相同的合理操作,但C标准和POSIX都没有定义其行为。标准很好,但也有注意事项。请阅读您系统的手册页面。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接