c - 如何防止无限标准输入循环?
问题描述
我正在尝试为练习题编写一个简单的程序,如下所示:
(销售佣金计算器) 一家大型化工公司以佣金为基础向其销售人员支付报酬。销售人员每周收到 200 美元,外加该周总销售额的 9%。例如,一个销售人员在一周内销售了价值 5000 美元的化学品,将获得 200 美元加上 5000 美元的 9%,即总共 650 美元。开发一个程序,输入每个销售人员上周的总销售额,并计算并显示该销售人员的收入。一次处理一位销售人员的数据。
我正在尝试处理用户是否输入数字以外的内容,例如字符串/字符。但是,当我尝试运行它并通过输入字符串/字符来测试它时,它会一直循环直到 VSC 崩溃。
我的代码:
#include <stdio.h>
#include <stdlib.h>
int main(void){
float sales = 0;
float salary = 0;
while (sales != -1)
{
printf("Enter sales in dollars (-1 to end): ");
scanf("%f", &sales);
while ((sales != -1) && !(sales >= 0))
{
puts("Input error, please try again");
fflush(stdin);
printf("Enter sales in dollars (-1 to end): ");
scanf("%f", &sales);
}
if (sales != -1)
{
salary = 200 + (0.09 * sales);
printf("Salary is: $%.2f\n", salary);
}
}
return 0;
}
我在另一个程序中使用了类似的方法,它工作得很好,所以我不知道这里有什么问题。
另一个程序的代码:
while(!(collected >= 0))
{
fflush(stdin);
puts("Input error, please try again.");
printf("Enter total amount collected (-1 to quit): $");
scanf("%f", &collected);
}
一个解释将不胜感激!
解决方案
scanf("%f", ...)
永远不会接受任何格式不正确的数字,所以如果你输入一个字符,你所有的scanf()
调用只会看到有一个字符被使用,但是格式说明符不允许它,它们不会读取任何内容并返回0
. while
如果输入任何不是有效数字的内容,这加上您的, 将导致无限循环。
您必须阅读直到行尾的所有内容,或者在scanf
返回时跳过不需要的字符0
(这意味着它无法正确读取任何值)。另外,检查是否scanf
返回EOF
,这意味着有错误或到达文件末尾。
无论如何,fflush(stdin)
是未定义的行为,永远不要这样做!
正确的方法是:
#include <stdio.h>
int main(void) {
float sales = 0;
float salary;
int res;
do {
printf("Enter sales in dollars (-1 to end): ");
fflush(stdout);
res = scanf("%f", &sales);
if (res == EOF) {
// Something bad happened.
if (feof(stdin))
fputs("End of input reached.\n", stderr);
else
perror("Error reading input");
return 1;
}
if (sales != -1 && sales < 0) {
// Perhaps it would be a better idea to say "invalid value" here?
puts("Input error, please try again.");
res = 0;
}
// Either the value was read correctly (res = 1) or it wasn't (res = 0).
// In any case, consume the rest of the line.
scanf("%*[^\n]");
} while (res != 1 && sales != -1.0);
if (sales != -1.0) {
salary = 200 + (0.09 * sales);
printf("Salary is: $%.2f\n", salary);
}
return 0;
}
推荐阅读
- github-actions - 错误:过程已完成,错误代码 1 – 自托管运行器上的 GitHub 操作
- python - 将 matplotlib 图转换为 json 对象
- css - 如何在网格显示中为每一行添加支撑线
- visual-studio-code - 文本结束后将 VSCode 装饰器应用于空白空间
- java - Spring无法从POST映射单个值
- error-handling - 来自 mozilla 的 NativeJSON.parse 的 RhinoException 没有 lineNumbers
- node.js - 如何在 tcp 套接字侦听器中唯一标识套接字 id
- powershell - 以编程方式获取 SharePoint Online 系统页面 html 内容
- node.js - MongoDb 没有与 express 连接
- php - 避免对 MySQL 日期时间列进行不必要的时间戳转换