繁体   English   中英

如何防止无限 stdin 循环?

[英]How do I prevent infinite stdin looping?

我正在尝试为练习题编写一个简单的程序,如下所示:

(销售佣金计算器)一家大型化工公司按佣金向其销售人员支付报酬。 销售人员每周收到 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;
}

暂无
暂无

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

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