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

C 語言 scanf 緩衝區殘留換行符導致輸入跳過問題詳解

     編輯:程式設計疑難解答

問題現象

執行以下加油計費程式時,第二個 scanf("%c", &s) 被跳過,直接讀到換行符,導致服務類型選擇失效:

printf("請輸入服務類型:\n");
printf("a.自己加\n");
printf("b.自助加\n");
scanf("%c", &s); // 這裡直接讀到上一個 scanf 留下的 '\n'

根本原因

scanf("%f", &x) 讀取浮點數後,緩衝區殘留換行符 \n。緊接著的 scanf("%c", &s) 讀取單一字元,直接消費這個換行符,而非使用者輸入的 'a' 或 'b'。

解決方案對比

方案一:fflush(stdin)(不推薦,非標準)

scanf("%f", &x);
fflush(stdin); // 僅 Windows/MSVC 支援,C 標準未定義
scanf("%c", &s);

方案二:在格式字串前加空白(推薦,標準做法)

scanf(" %c", &s); // 空白會跳過所有空白字元(含 \n、\t、空格)

方案三:使用 getchar() 吞噬換行符

scanf("%f", &x);
getchar(); // 讀走殘留的 \n
scanf("%c", &s);

方案四:改用 fgets + sscanf(最穩健)

char buf[32];
fgets(buf, sizeof(buf), stdin);
sscanf(buf, "%f", &x);

fgets(buf, sizeof(buf), stdin);
sscanf(buf, " %c", &s);

修正後完整程式碼

#include <stdio.h>
#include <stdlib.h>

int main() {
    float x, y, z, k;
    char s, q;
    
    printf("請輸入加油量:\n");
    scanf("%f", &x);
    
    printf("請輸入服務類型:\n");
    printf("a.自己加\n");
    printf("b.自助加\n");
    scanf(" %c", &s); // 關鍵:前面加空白
    
    switch(s) {
        case 'a': z = 0.95; break;
        case 'b': z = 0.90; break;
        default:  printf("error\n"); return 1;
    }
    
    printf("請輸入汽油品種:\n");
    scanf(" %c", &q); // 同樣加空白
    
    switch(q) {
        case 'a': y = 3.25; break;
        case 'b': y = 3.00; break;
        case 'c': y = 2.75; break;
        default:  printf("error\n"); return 1;
    }
    
    k = x * y * z;
    printf("所購汽油價格:%.2f\n", k);
    return 0;
}

最佳實務總結

場景建議寫法說明
讀取單一字元scanf(" %c", &ch)前置空白跳過空白字元
讀取字串scanf("%s", str)自動跳過前導空白
混合輸入fgets + sscanf逐行讀取,避免緩衝區殘留

核心原則:%c 是唯一不自動跳過空白字元的格式指示符,使用時務必在前面加空白或預先清理緩衝區。

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