簡體   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