int m;
while (scanf("%d", &m)) {
char str[10][10];
for (int i = 0; i < 5; i++) {
printf("請輸入第%d個字符:", i+1);
scanf("%s", str[i]);
}
}
執行結果:
3
請輸入第1個字符:請輸入第2個字符:1
請輸入第3個字符:2
請輸入第4個字符:34
請輸入第5個字符:3
第一次 printf 後直接跳過輸入,顯示第二個提示。
scanf("%d", &m) 讀取整數 3,留下換行符 \n 在 stdin 緩衝區。scanf("%s", str[0]):%s 會跳過空白字元(含 \n),直接等待非空白輸入,因此 printf 輸出後緊接著下一次 printf,使用者來不及輸入。%s 讀取的是 1(給 str[0]),導致後續邏輯錯位。int c;
while ((c = getchar()) != '\n' && c != EOF); // 讀取並丟棄剩餘字元
在 scanf("%d", &m) 後、進入迴圈前呼叫。
fgets + sscanfchar line[100];
while (fgets(line, sizeof(line), stdin)) {
if (sscanf(line, "%d", &m) != 1) continue;
for (int i = 0; i < 5; i++) {
printf("請輸入第%d個字符:", i+1);
fgets(str[i], sizeof(str[i]), stdin);
str[i][strcspn(str[i], "\n")] = '\0'; // 移除換行
}
}
cin(若允許 C++)int m;
string s;
while (cin >> m) {
for (int i = 0; i < 5; i++) {
cout << "請輸入第" << i+1 << "個字符:";
cin >> s; // 自動跳過空白,不留殘留
strcpy(str[i], s.c_str());
}
}
| 函數 | 行為 | 殘留字元 |
|---|---|---|
scanf("%d") | 讀整數,跳過前導空白 | 留下後續空白(含 \n) |
scanf("%s") | 讀字串,跳過前導空白 | 留下後續空白 |
gets() | 讀整行(含空白),遇 \n 停止 | 丟棄 \n,不留殘留 |
getchar() | 讀單一字元 | 無 |
fgets() | 讀指定長度或遇 \n | 保留 \n 於緩衝區 |
fgets 讀行,再用 sscanf 解析。scanf 返回成功匹配項數,EOF 表輸入結束。gets:無緩衝區長度檢查,極易溢位,C11 已移除。\r\n、Linux \n,用 strcspn(str, "\r\n") 通用移除。