scanf函数读取字符串时的长度条件
区别的核心只有一个:是否限制最大读取长度(安全性)。
一句话结论(先记住)
scanf("%59999s", s)是安全写法,scanf("%s", s)是不安全写法。
一、它们在“做什么”上的区别
scanf("%s", s);
- 读取任意长度的“非空白字符串”
- 不检查数组大小
- 如果输入比
s的容量大 → 缓冲区溢出(UB)
scanf("%59999s", s);
- 最多读取 59999 个字符
- 给字符串末尾留 1 个位置放
'\0' - 保证不会写越界
这里的
59999必须 ≤数组容量 - 1
二、为什么加数字就“安全”了?
%s 的完整格式其实是:
%[最大宽度]s
你写的:
char s[60000];
scanf("%59999s", s);
意思是:
最多读 59999 个字符,然后自动补
'\0'
所以最多占用:
59999 + 1 = 60000
正好等于数组大小,完全不越界。
三、如果不用宽度限制,会发生什么?(关键)
例子
char s[10];
scanf("%s", s);
输入:
abcdefghijklmnop
结果:
scanf会一直写- 覆盖
s后面的内存 - 可能:
- 程序崩溃
- 输出乱码
- 静默错误(最危险)
👉 这是 C 里最经典、最致命的 bug 来源之一
四、对比表(非常建议记)
| 写法 | 是否限制长度 | 是否可能溢出 | 是否推荐 |
|---|---|---|---|
scanf("%s", s) |
❌ 否 | ✅ 会 | ❌ 不推荐 |
scanf("%59999s", s) |
✅ 是 | ❌ 不会 | ✅ 推荐 |
五、那为什么很多教材/代码还在用 %s?
原因只有两个:
- 示例代码为了简短
- 假设输入“绝对安全”(OJ 已保证长度)
但在真实代码 / 好习惯 / 面试中:
永远不要相信输入是安全的
六、和 fgets 的关系(顺便一提)
fgets(s, sizeof(s), stdin);
- 本身就带长度限制
- 能读空格
- 更安全
但:
- 会读入
'\n' - 需要额外处理
所以:
- 读单词 →
scanf("%Ns", s) - 读整行 →
fgets
七、一句话总结(背下来)
scanf("%s", s)不限制长度,可能越界;
scanf("%Ns", s)明确限制最大读取字符数,是安全写法。

浙公网安备 33010602011771号