我写了一个练习的解决方案,要求编写一个程序,作为一个简单的“打印”计算器,并检测除零并检查未知的操作符。
当输入预期的运算符时,程序按预期工作。例如:
“100 S”打印“= 100.000000”
“2 /”打印“= 50.000000”
“10 *”打印“= 500.000000”
它还可以检测零除以及未知运算符。
然而,当我以错误的顺序输入运算符时,如下所示: “/ 2”或“* 10”,程序陷入循环。
如何修复此错误,以便在以错误的顺序输入运算符时,它只会打印“未知运算符”?
// Write a program that acts as a simple "printing" calculator
#include <stdio.h>
int main (void)
{
float acc, b;
char operator;
printf ("Begin Calculations\n");
while ( operator != 'E') {
scanf ("%f %c", &b, &operator);
switch (operator)
{
case 'S': // set accumulator
case 's':
acc = b;
printf ("= %f\n", acc);
break;
case 'E': // end program
case 'e':
printf ("= %f\nEnd of Calculations.\n", acc);
break;
case '+':
printf ("= %f\n", acc += b);
break;
case '-':
printf ("= %f\n", acc -= b);
break;
case '*':
printf ("= %f\n", acc *= b);
break;
case '/':
if ( b == 0 )
printf ("Can't divide by zero.\n");
else
printf ("= %f\n", acc /= b);
break;
default:
printf ("Unknown operator.\n");
break;
}
}
return 0;
}
更新:我找到了解决方案
while ( operator != 'E' && operator != 'e' ) {
if ( scanf ("%f %c", &b, &operator ) < 2 ) {
printf ("Error. You need to enter a number.\n");
break;
}
else {
switch (operator)...
答案 0 :(得分:1)
scanf
的结果是分配的字段数。如果scanf
返回0,则每次调用它时,它将返回0
相同的格式字符串。因为scanf
推回了它读取的最后一个与输入序列(%f
)不匹配的字符,它会反复尝试反复转换相同的字符串。
这就是你无限循环的原因。您可能想要检查scanf
的结果。如果它小于2,则输出错误。
答案 1 :(得分:0)
我认为你需要让你的输入程序比scanf(显然)更强大。例如,如果您以整行读取输入,则可以解析它们(例如,使用sscanf)以使组件不会混淆输入流。
答案 2 :(得分:0)
scanf正在读取,直到它可以解析浮点数。尝试使用gets来读取字符串,然后从那里解析该字符串。
答案 3 :(得分:0)
我想退出你需要输入一个浮点+'E'(0.0 E)而不只是'E'。那会是你要问的吗?
啊!我看到你提到放下东西。是。 scanf()永远不会检测到它。
如果你在Linux下,请查看lex和yacc(或者说flex和bison是准确的。)要做这些事情,它会好很多,你可以做得更好(支持括号,减号和加号)运算符,而不仅仅是加减,等等。)
答案 4 :(得分:0)
它不是“卡在一个循环中”,它正在等待操作员这一行:
scanf ("%f %c", &b, &operator);
承诺。该行读取,直到它收到一个浮点数,然后它读取一个运算符。如果你先给它一个操作员,它就会忽略它。
(顺便说一句,您应该在operator
之前将while ( operator != 'E') {
初始化为特定内容,因为据您所知,operator
可能恰好以{{1}开头另外,正如Mysticial所说,'E'
不是C标识符的好名字,因为它在C ++中的用途。)
答案 5 :(得分:0)
问题是scanf()试图读取你告诉它的内容,即浮点数和字符。当你键入scanf返回的另一种方式,因为它不是你告诉它的格式,但不幸的是它WONT刷新缓冲区,所以while会再次进行,scanf再次尝试读取,依此类推。
删除scanf,但如果这只是作业,你可以尝试:
if (!scanf ("%f %c", &b, &operator)) {
scanf ("%*[^\n]"); /* TRY to flush stdin */
printf("Incorrect input!");
incorrect_input++;
continue;
} else {
incorrect_input = 0;
}
if (incorrect_input > 5) {
break; /* Very simple measure to avoid getting stuck in the loop */
}
答案 6 :(得分:0)
然而,当我以错误的顺序输入运算符时,如:“/ 2”或“* 10”,程序陷入循环。
如何修复此错误,以便在以错误的顺序输入运算符时,它只会打印“未知运算符”?
您可能想要读取整个表达式,然后解析它是否正确。有各种表达式表示方法(infix,postfix (also known as reverse polish notation)和prefix (otherwise known as polish notation)),这使得验证和评估它们的任务变得更加容易。
如果您已经或可以掌握Dennis Ritchie和Brian Kernighan撰写的“The C Programming Language”书,请转到第4章并阅读指导您完成计算器程序设计和实施的部分。