比较 C 中的 scanf()、gets() 和 fgets() 函数
在 C 语言中,处理字符串输入主要使用 scanf()
, gets()
, 和 fgets()
函数。这些函数在用途和安全性方面有所不同。
1. scanf() 函数
scanf()
是用于读取格式化输入的函数。使用 %s
格式化标识符来读取字符串,但它会在读取到空格或换行符时停止。这使得 scanf()
不适合读取含有空格的字符串。
示例:
cchar str[50]; printf("Enter a string: "); scanf("%s", str);
这段代码只会读取空格之前的部分。
缺点:
- 无法读取空格后的字符串。
- 当输入超过定义的数组长度时,可能会导致缓冲区溢出,这是一个安全隐患。
2. gets() 函数
gets()
函数用于从标准输入读取字符串,直到遇到换行符 \n
。它不考虑字符串的长度,这可能会导致缓冲区溢出。
示例:
cchar str[50]; printf("Enter a string: "); gets(str);
尽管 gets()
可以读取含有空格的整行数据,但它被认为是非常不安全的,因为它不检查目标缓存的大小。
缺点:
- 高风险的安全漏洞,因为它不进行长度检查。
- 已在最新的 C 标准中被弃用。
3. fgets() 函数
fgets()
函数是一个更安全的选择,它从文件或输入流中读取字符串,直到达到指定的字符数或遇到换行符,以先到者为准。它包含了一个参数来限制读取的字符数,从而避免缓冲区溢出。
示例:
cchar str[50]; printf("Enter a string: "); fgets(str, 50, stdin);
这个函数读取至多 49 个字符(第 50 个位置留给终止的 \0
)或直到换行符为止。这包括空格和可能的换行符。
优点:
- 提供缓冲区溢出的保护。
- 能够读取含有空格的字符串。
结论:
在进行字符串输入时,推荐使用 fgets()
因为它提供了更好的安全性。尽管 gets()
和 scanf()
在某些情况下看似方便,但它们的使用会带来安全风险,特别是在处理不确定长度的输入时。fgets()
提供了一个平衡点,既能读取空格,又能防止缓冲区溢出。
2024年6月29日 12:07 回复