| 函數 | 特點 | 空格處理 | 緩衝區殘留 |
| scanf("%s", str) | 格式化讀取單詞 | 遇空格/換行停止 | 留在緩衝區,下次 scanf 直接讀取 |
| gets(str) | 讀取整行 | 包含空格,遇換行停止 | 消耗換行符,無殘留 |
scanf 讀取字符串的關鍵行為
1. 遇空格截斷
scanf("%s", str2); // 輸入 "Java Python C-Sharp"
printf("%s", str2); // 輸出 "Java"
2. 緩衝區殘留導致連續讀取
scanf("%s", str1); // 讀 "Java",留 " Python C-Sharp\n"
scanf("%s", str2); // 直接讀 "Python",不等待輸入
scanf("%s", str3); // 直接讀 "C-Sharp"
為什麼 scanf 字符串不加 &?
數組名 本身就是首元素地址(首地址)。
char str[20]; → str 等價於 &str[0]
scanf("%s", str); 正確,scanf("%s", &str); 錯誤(類型不匹配)
gets 讀取整行(含空格)
#include <stdio.h>
int main() {
char str1[30], str2[30];
gets(str1); // 輸入 "Java Python C-Sharp"
gets(str2); // 輸入 "https://c.biancheng.net"
printf("str1: %s\nstr2: %s\n", str1, str2);
return 0;
}
運行結果
str1: Java Python C-Sharp
str2: https://c.biancheng.net
scanf vs gets 選擇指南
| 需求 | 推薦函數 | 理由 |
| 單詞(無空格) | scanf("%s") | 簡潔、自動分詞 |
| 整行(含空格) | fgets(str, n, stdin) | 安全、可限長度、標準替代 gets |
| 教學演示整行 | gets() | 簡單但不安全,已從 C11 標準移除 |
安全警告:gets 無長度限制,極易導致緩衝區溢出攻擊,實際開發嚴禁使用。請改用 fgets(str, sizeof(str), stdin),並手動去除末尾 \n。
字符串輸入輸出最佳實踐
- 輸出:優先
puts(自動換行)或 printf("%s\n")
- 輸入單詞:
scanf("%99s", str)(限制長度防溢出)
- 輸入整行:
fgets(str, sizeof(str), stdin) + 去除 \n
- 理解緩衝區機制,避免殘留字符干擾後續讀取
- 上一篇文章: C語言數組總結與實戰應用:定義、初始化、越界防範、排序查找預備
- 下一篇文章: C語言字符串處理函數庫:strlen、strcat、strcpy、strcmp 完整指南
Copyright ©
程式碼之家 All Rights Reserved