問題現象
scanf("%s", str);
輸入:hello world
結果:str = "hello" // 空格截斷
方案一:scanf 掃描集 %[^\n]
scanf("%[^\n]", str); // 讀取直到換行(含空格)
// 或
scanf("%[^ ]", str); // 讀取直到空格
掃描集語法:
%[abc]:只讀 a/b/c
%[a-z]:讀小寫字母
%[^abc]:讀除 a/b/c 外任意字元
%[^a-z]:讀非小寫字母
方案二:gets / fgets 讀整行
| 函式 | 緩衝區檢查 | 保留換行 | 建議 |
| gets(str) | 無(危險) | 否 | 禁用 |
| fgets(str, n, stdin) | 有(安全) | 是 | 推薦 |
char buf[100];
fgets(buf, sizeof(buf), stdin);
// buf 含 \n,需手動移除
buf[strcspn(buf, "\n")] = '\0';
方案三:逐字元讀取
int i=0, ch;
while ((ch=getchar())!='\n' && ch!=EOF && i
補充:scanf 進階技巧
- 丟棄不需要的字元:
scanf("%*c%*d", &x); * 表讀取但不賦值。
- 吃掉殘留換行:
scanf("%c%*c", &ch); 讀字元後丟棄下一字元(通常是 \n)。
- 非空白字元匹配:格式串中非格式字元會匹配輸入並丟棄,如
scanf("%d,%d", &a, &b); 會吃掉逗號。
安全性總結
- gets 已從 C11 標準移除,絕對不要用。
- fgets + 手動去 \n 是最穩健的通用做法。
- scanf 掃描集 適合簡單格式,但需注意緩衝區溢位(無長度限制),建議搭配寬度
%99[^\n]。
- 上一篇文章: HDU 4587 TWO NODES:雙連通分量與割點應用,求移除兩點後最大連通塊
- 下一篇文章: 兩個經典奇葩 C 程式深度解析:遞迴 main 與陣列下標交換律
Copyright ©
程式碼之家 All Rights Reserved