首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 語言驗證碼程式 Bug:倒數計時殘留輸出導致後續輸入比對失敗

     編輯:程式設計疑難解答

Bug 現場

驗證碼錯誤 3 次後,倒數 10 秒(for(countdown=10; countdown>0; countdown--)),每秒 system("cls") 清屏並 printf("%d", countdown)。倒數結束後,用戶輸入正確驗證碼卻仍判定錯誤。

根因

倒數迴圈最後一次執行時:

  1. countdown=1,system("cls") 清屏。
  2. printf("%d", 1) 輸出 1 並**留在緩衝區/螢幕上**(無換行符)。
  3. 迴圈結束,程式繼續回到主迴圈 scanf("%d", &number) 等待輸入。
  4. 螢幕顯示 1,用戶輸入正確數字(如 123),實際輸入緩衝區變為 1123(殘留的 1 + 用戶輸入),scanf 讀取整數 1123,與驗證碼不符 → 判定錯誤。

修正代碼

for (countdown = 10; countdown > 0; countdown--) {
    system("cls");
    printf("%d", countdown);
    fflush(stdout);  // 強制刷新輸出緩衝區,確保立即顯示
    Sleep(1000);
}
system("cls");  // 倒數結束後**再清一次屏**,清除殘留的 '1'

更佳實踐:避免 system("cls") 與 Sleep 的可移植性/效能問題

#ifdef _WIN32
    #include <windows.h>
    #define CLEAR_SCREEN() system("cls")
    #define SLEEP_MS(ms) Sleep(ms)
#else
    #include <unistd.h>
    #define CLEAR_SCREEN() printf("\033[H\033[2J")  // ANSI 轉義序列清屏
    #define SLEEP_MS(ms) usleep((ms)*1000)
#endif

for (int cd = 10; cd > 0; --cd) {
    CLEAR_SCREEN();
    printf("請等待 %d 秒...\n", cd);
    fflush(stdout);
    SLEEP_MS(1000);
}
CLEAR_SCREEN();  // 關鍵:清除最後殘留輸出

核心教訓

  1. 控制台輸出無換行時會殘留,下一次 scanf 會讀取殘留字元 + 用戶新輸入。
  2. 互動式程式每次提示/清屏後必須 fflush(stdout),確保用戶看到最新狀態。
  3. 倒數/進度條類輸出結束後,務必清除殘留內容(再清屏或輸出換行覆蓋)。
  4. 避免 system() 呼叫外部命令(安全風險、效能差、跨平台麻煩),改用 ANSI 轉義序列或平台 API。

總結: Bug 非邏輯錯誤,而是**控制台輸出殘留干擾輸入**。加上倒數結束後的 system("cls") / CLEAR_SCREEN() 即可徹底修復。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved