簡體   English   中英

忽略 while 循環中的 scanf 值

[英]Ignoring scanf value in while loop

我正在學習 C 並且在運行此循環時遇到問題。 我寫了一個while循環來提示用戶輸入 package 及其數量。 我嘗試驗證輸入的數量以檢查是否為 integer(當用戶鍵入一個字符時,它會提示用戶再次鍵入)

對於第一次運行,一切都很好。

但是當循環運行第二次等等時,我嘗試輸入一個字符來表示 package 的數量,不會彈出消息告訴用戶再次輸入。

scanf的值被忽略, tempQtty的值等於用戶鍵入的先前數量。

有什么辦法可以解決這個問題,還是有另一種方法來驗證用戶輸入是 integer?

抱歉我的英文不好:")[輸入,預期輸入和實際輸入][1]

while(skip != 'x')
        {
            printf("\n\n%27sPACKAGE A/B/C/D  ( x = skip ) : ", "");
            rewind(stdin);
            package = getchar();

            switch (package)
            {
            case'x':case'X': skip = tolower(package); break;
            case'A':case'a':case'B':case'b': case'C':case'c':case'D':case'd':
                printf("%27sQUANTITY%21s: ", "", "");
                rewind(stdin);
                scanf("%d", &tempQtty);   //here's the problem

                while (tempQtty < 0)
                {
                    printf("%27s(PLEASE KEY IN A CORRECT VALUE!)\n", "");
                    printf("%27sQUANTITY%21s: ", "", "");
                    rewind(stdin);
                    scanf("%d", &tempQtty);
                }
                switch (package)
                {
                case 'A':case 'a': qttyA = tempQtty; totalQttyA += tempQtty; break;
                case 'B':case 'b': qttyB = tempQtty; totalQttyB += tempQtty; break;
                case 'C':case 'c': qttyC = tempQtty; totalQttyC += tempQtty; break;
                case 'D':case 'd': qttyD = tempQtty; totalQttyD += tempQtty; break;
                    
                }
                break;
                default:
                    printf("%27s(NO SUCH PACKAGE! PLEASE KEY IN AGAIN!)\n", "");
            }
        }
printf("\nA = %d", qttyA);
printf("\nB = %d", qttyB);


  [1]: https://i.stack.imgur.com/hBD82.png

我試着輸入package這個號碼的字符,不會彈出提示讓用戶再次輸入。

scanf的值被忽略, tempQtty的值等於用戶鍵入的先前數量。

有什么辦法可以解決這個問題,還是有另一種方法來驗證用戶輸入是 integer?

如果您輸入z ,您認為tempQtty將收到負值的假設是沒有根據的。 事實上,C 標准要求如果轉換失敗, tempQtty不受影響。 解決這個問題的方法不要忽略scanf返回值,它告訴輸入是否有效。

首先,正如我在評論中提到的,這是一個異常復雜的問題,面對它的並不只有你一個人。 不是你的問題,也不是C語言的問題; 這基本上只是scanf function 本身的問題。

部分答案:

(1) 到處都有類似的東西

scanf("%d", &tempQtty);
while (tempQtty < 0)
    ...

那是錯誤的。 如果您使用%d請求 integer 輸入,並且如果用戶鍵入非數字內容,則scanf不會將tempQtty填寫為 -1。 所做的是返回一個值,表示它無法轉換您(程序員)所要求的內容。 所以你想把它改成更像

while (scanf("%d", &tempQtty) != 1)
    ...

(2) 如果用戶沒有鍵入您請求的 integer,並且如果scanf返回 0 告訴您,則存在問題:用戶鍵入的非數字輸入可能仍然位於輸入 stream 上。看起來您可能已經意識到這一點,並且您正試圖通過調用rewind(stdin)來擺脫未讀的輸入。 但那是行不通的; 那不是這樣做的方法。

你想要做的是像這樣寫一個小“幫手”function:

void flush_unread_input()
{
    int c;
    do {
        c = getchar();
    } while(c != EOF && c != '\n');
}

然后,只要檢測到錯誤(即scanf返回 1 以外的值),而不是調用rewind(stdin) ,只需調用flush_unread_input()

還有幾點:

  • 您可能必須試驗在哪里調用flush_unread_input以及在哪里不調用。 你不能盲目地將它灑在任何地方,因為它基本上讀取並丟棄該行的 rest,但這意味着它也可以讀取並丟棄整行,有時這可能是你真正想要的一行。
  • 有很多寫flush_unread_input function 的方法。我已經展示了一種應該很容易理解的方法,但是你會經常看到更緊湊的東西,比如while((c = getchar());= EOF && c != '\n'); . (我還沒有測試我在這里展示的版本。)
  • 我的回答可能表明scanf如果成功則返回 1,如果失敗則返回 0,但它比這更復雜。 scanf實際上返回成功轉換和存儲的項目數,如果您的格式說明符中包含多個%符號,則該數可能大於 1。

關於這個話題還有很多話要說,但今天早上我沒有時間寫更長的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM