使用 scanf("%f", &var) 讀取浮點數時,若輸入 (2-1)、21、1 等非法字符,程序陷入死循環或跳過後續輸入。根因在於 輸入緩衝區殘留字符。
scanf 時,從殘留字符開始嘗試匹配
scanf("%f", &chinese); // 輸入 "2-1\n" → 讀取 2.0,緩衝區剩 "-1\n"
scanf("%f", &english); // 嘗試讀取 "-1" → 失敗,english 不變,緩衝區仍剩 "-1\n"
// 讀取並丟棄緩衝區中直到換行符的所有字符
int c;
while ((c = getchar()) != '\n' && c != EOF); // 兼容無換行符結尾
// 或使用 scanf 格式字符串 (不推薦,易出錯)
// scanf("%*[^\n]"); scanf("%*c"); // 含陷阱,見下文
%*[^\n] 讀取並丟棄非換行符字符,**若緩衝區首字符即為 \n,則匹配失敗,不消耗字符**%*c 讀取該 \n,但若上一步失敗,緩衝區仍有非法字符
// 封裝安全輸入函數
int safe_scanf_float(float* out) {
char buf[64];
if (!fgets(buf, sizeof(buf), stdin)) return 0; // 讀整行
return sscanf(buf, "%f", out) == 1; // 解析
}
// 使用示例
float score;
printf("請輸入語文成績: ");
while (!safe_scanf_float(&score) || score < 0 || score > 100) {
printf("輸入無效,請重新輸入 (0-100): ");
}
scanf 返回值(成功匹配的項數)徹底理解標準輸入流與緩衡機制,是從「能跑通」邁向「健壯可靠」的分水嶺。