如何解决C 中的计算器应该只接受浮点数/整数数
我正在开发一个只有基本运算符的小计算器。它工作得很好,就像我想要的那样。但是有一个小问题。
我的程序在一个循环中,所以用户理论上可以在每次计算后再次使用它。
但我也希望程序能够区分 float
类型的数字和其他所有元素,因此它只接受浮点数或整数。
问题来了: 如果我输入一个字母字符,问题就会变得混乱并且循环不正确。 输入一些随机字母而不是预期的两个数字时,您可以自己尝试一下。
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
int main()
{
float num1,num2,result = 0;
int menu;
while (1) //so that the program basically never stops
{
printf("--- Taschenrechner ---\n\n"
"1. Addition\n"
"2. Subtraktion\n"
"3. Multiplikation\n"
"4. Division\n"
"5. Beenden\n"
"Wählen Sie Ihren gewünschten Operator aus (oder auch nicht): ");
// it is like the calculators menu,distinguishing between
// addition,subtraction,multiplication,division and exit
scanf("%d",&menu);
if (menu >= 5 || menu < 1)
{
printf("\nDas Programm wurde beendet,schade. Bis zum nächsten Mal!"); //if the given integer is 5 or not part of the menu,the program should stop
break;
}
printf("\n\nGeben Sie nun zwei Zahlen ein:\n"); //user should provide two numbers
scanf("%f",&num1);
printf("\n");
scanf("%f",&num2);
if ((isalpha(num1) || isalpha(num2)) == 0) //if the given elements are no numbers at all,in this case part of the alphabet,the program should stop
{
printf("Gut!");
} else
{
printf("Break");
break;
}
switch (menu)
{
case 1:
result = num1 + num2;
break;
case 2:
result = num1 - num2;
break;
case 3:
result = num1 * num2;
break;
case 4:
result = num1 / num2;
break;
default:
printf("\n\nUps,da ist wohl etwas mit den Operatoren schief gelaufen. Versuchen Sie es erneut!"); //here again,if something went wrong within the switch case,program should stop
break;
}
printf("\n\nPerfekt,das hat geklappt!");
sleep(1); //this is just for delaying the result
printf("\n\nIhr Ergebnis wird berechnet\nErgebnis: %.2f\n\n\n",result);
sleep(3);
}
return 0;
}
我真的不知道如何解决这个问题,已经尝试了好几天了。解决方案可能真的很简单,但我就是不明白。 一点帮助会非常好。 :)
而且也不介意程序是德语的。我已经将一些内容解释为评论。
解决方法
您应该检查 scanf
返回的值。例如:if( scanf("%d",&menu) == 1 ) { ... }
。如果输入流的下一个字符不是有效整数的一部分,则上述 scanf
将返回 0。
通常,您应该始终检查 scanf 返回的值。
,为确保用户输入有效输入,您应验证 scanf()
操作是否成功,并在数据无效时要求用户重新输入。 scanf()
返回成功转化的次数。如果输入无效,您应该读取并丢弃当前输入行的其余部分。
还要注意 if ((isalpha(num1) || isalpha(num2)) == 0)
是不正确的:它测试 num1
或 num2
是否是 ASCII 字母的代码。如果使用类型 65
或 97
...
这是修改后的版本:
#include <stdio.h>
#include <unistd.h>
int main() {
float num1,num2,result = 0;
int menu;
while (1) { //so that the program basically never stops
printf("--- Taschenrechner ---\n\n"
"1. Addition\n"
"2. Subtraktion\n"
"3. Multiplikation\n"
"4. Division\n"
"5. Beenden\n"
"Wählen Sie Ihren gewünschten Operator aus (oder auch nicht): ");
// it is like the calculators menu,distinguishing between
// addition,subtraction,multiplication,division and exit
if (scanf("%d",&menu) != 1 || // invalid menu entry,bail out
menu >= 5 || menu < 1) {
printf("\nDas Programm wurde beendet,schade. Bis zum nächsten Mal!"); //if the given integer is 5 or not part of the menu,the program should stop
break;
}
for (;;) {
printf("\n\nGeben Sie nun zwei Zahlen ein:\n"); //user should provide two numbers
if (scanf("%f%f",&num1,&num2) == 2)
break;
printf("\nUngültige Eingabe\n");
if (scanf("%*[^\n]") == EOF) // discard the rest of the input line
return 1;
}
switch (menu) {
case 1:
result = num1 + num2;
break;
case 2:
result = num1 - num2;
break;
case 3:
result = num1 * num2;
break;
case 4:
result = num1 / num2;
break;
default:
printf("\n\nUps,da ist wohl etwas mit den Operatoren schief gelaufen. Versuchen Sie es erneut!\n");
//here again,if something went wrong within the switch case,program should stop
return 1;
}
printf("\n\nPerfekt,das hat geklappt!");
sleep(1); //this is just for delaying the result
printf("\n\nIhr Ergebnis wird berechnet\nErgebnis: %.2f\n\n\n",result);
sleep(3);
}
return 0;
}
注意事项:
-
scanf()
无法转换 2 个浮点数的原因有两个:- 文件过早结束,
- 流中不能作为数字开头的违规字符,例如
A
或%
。
-
要刷新用户输入的行的剩余部分,可以使用循环:
int c; while ((c = getchar()) != EOF && c != '\n') continue; if (c == EOF) { /* no more characters available from stdin: bail out */ return 1; }
或者可以使用 scanf()
转换格式,该格式将读取并丢弃所有字符直到换行符:
if (scanf("%*[^\n]") == EOF) // discard the rest of the input line
return 1;
解释如下:
-
*
之后的%
阻止存储转换后的值,转换说明符不需要指针。 -
[...]
指定一个 scanset,一组接受或拒绝的字符。[abcx-z]
接受a
、b
、c
、x
、z
的任何非空组合以及x
之间的任何字符和z
(ASCII 字符集中的y
)。[^\n]
接受任何不同于\n
的非空字符序列,因此输入行的其余部分(如果有)。 - 用户输入的无法与行的其余部分一起转换的字符将被读取并丢弃,使换行符挂起。
- 如果在换行符之前没有这样的字符可用,
scanf()
返回0
并且换行符仍在等待下一次%f
转换; - 如果流立即到达文件末尾,
scanf()
将返回EOF
,这将导致程序退出。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。