C语言 不安全的gets()
本文将探究不安全的 gets() 和它的替代品。
一、问题
在 C 语言中,gets() 常被用于读入字符串。它有着能够读取一行字符(包括空格),且简单易用的特点。但它可能因为输入过多而出现越界问题。函数仅仅知道数组位置,而不知道数组的大小,如果输入的字符串过长,会导致缓冲区溢出,即多余的字符放置在数组之外。如果这些多余的字符只是占用了尚未使用的内存,则不会立即出现问题。但如果它们占据了已被使用的内存,并对其进行了擦写,则可能导致出现重大错误。
gets() 对此没有任何解决方法。
C99 标准承认了此函数的问题并建议不要使用该函数, C11 正式从标准中废除了该函数。
二、解决办法
1.scanf
scanf 也可以读取字符串,虽然和 gets() 一样,都可能因为输入过多而出现越界问题。但它可以通过增加修饰符,限定输入量的方法解决,例如:
1 |
|
2.fgets()
用于从文件中读取字符串,也可用于从键盘中读取字符(stdin),用法如下:
1 |
|
读取 len-1 个字符
将会保留换行符,添加’\0’
例如:
1
2输入: a 、 b 、 c 、 回车
存储: 'a'、'b'、'c'、'\n'、'\0'不会清空缓存区,可以继续读入
3.gets_s()
gets_s() 是 C11 新增的可选函数,编译器不一定支持
从标准输入中读取字符串,用法如下:
1 |
|
读取 len-1 个字符
将会舍弃换行符,添加’\0’
会自动清空缓存区
三、总结
函数 | 用法 | 是否安全 | 清空缓存区 | 特点 |
---|---|---|---|---|
gets() | gets(数组) | 不安全 | 全部读入 | 整行读入,丢弃换行符,添加’\0’ |
scanf | scanf(“%(len-1)s”, 数组) | 安全 | 否 | 读入一个单词,添加’\0’ |
fgets() | fgets(数组, len, 文件) | 安全 | 否 | 整行读入,保留换行符,添加’\0’,可以从文件读入 |
gets_s() | gets_s(数组, len) | 安全 | 是 | 整行读入,丢弃换行符,添加’\0’ |
参考
- C Primer Plus
- C程序设计
- C 语言教程 | 菜鸟教程