for (;;) {
printf("Enter a value: ");
scanf("%lf", &value); // 第一次正常讀入數字
// ...
printf("Continue? (Y/N): ");
scanf("%c", &answer); // ❌ 直接讀到上次殘留的 '\n',不等待輸入
if (tolower(answer) == 'n') break;
}
第二次 scanf("%c") 不會阻塞,因為標準輸入緩衝區還留著上一輪 %lf 讀完後的 \n。
%lf 讀取浮點數,遇到非數字字符(如 \n)停止,**將該字符推回緩衝區**。%c 讀取**下一個字符**(包括空白、換行),不跳過任何字符。\n 被 %c 讀走,程序誤以為用戶輸入了空字符。scanf(" %c", &answer); // 格式串開頭的空格 = 跳過任意數量空白字符(含 \n、空格、Tab)
✅ 無額外函數調用,可移植,C89 起標準行為。
scanf("%lf", &value);
while (getchar() != '\n'); // 循環讀取並丟棄,直到吃掉換行符
scanf("%c", &answer);
⚠️ 若緩衝區已空(如重定向輸入),會陷入死循環,需改為 int c; while ((c=getchar())!='\n' && c!=EOF);。
char line[64];
fgets(line, sizeof(line), stdin); // 讀整行含 \n
sscanf(line, "%lf", &value); // 從行緩衝區解析,不影響 stdin
fgets(line, sizeof(line), stdin);
sscanf(line, " %c", &answer); // 同理
✅ 徹底隔離解析邏輯與輸入流,防溢出、易錯誤處理、適合混合輸入場景。
fflush(stdin); // 僅 MSVC 支援,GCC/Clang/Linux 下行為未定義(可能無效或崩潰)
❌ 跨平台代碼**嚴禁使用**。
#include <stdio.h>
#include <ctype.h>
int main() {
double total = 0, value;
int count = 0;
char line[64];
while (1) {
printf("Enter a value: ");
if (!fgets(line, sizeof(line), stdin)) break; // EOF 或錯誤
if (sscanf(line, "%lf", &value) != 1) {
puts("無效數字,重試。");
continue;
}
total += value;
count++;
printf("Continue? (Y/N): ");
if (!fgets(line, sizeof(line), stdin)) break;
char ans;
if (sscanf(line, " %c", &ans) != 1) continue;
if (tolower(ans) == 'n') break;
}
if (count) printf("Average = %.2f\n", total / count);
return 0;
}
scanf(" %c", ...) 格式串加空格(只修一字符)。fgets 讀行 + sscanf 解析,徹底規避緩衝區殘留問題。fflush(stdin),它不是標準 C。