C 库函数 - gets()
在 C 语言中,gets() 是一个用于从标准输入读取字符串的经典函数。虽然它使用简单,但需要注意安全性问题。
gets() 函数从 标准输入 stdin 读取一行字符串,并将其存储在指定的字符数组中。它会读取字符直到遇到换行符或文件末尾为止。
重要警告:gets() 存在严重的安全漏洞,无法指定缓冲区大小,容易导致缓冲区溢出。因此在现代 C 编程中,fgets() 是更好的选择。
单词释义:get 是"获取"的意思,s 代表"字符串" (string),合起来就是"获取字符串"。
基本语法与参数
gets() 是 C 标准库中的一个函数,需要包含头文件 <stdio.h>。
语法格式
char *gets(char *str);
参数说明
- 参数:
str- 类型:
char *(指向字符数组的指针) - 描述: 一个指向字符数组的指针,该数组用于存储读取到的 C 字符串。需要确保数组足够大,能够容纳输入的字符串。
- 类型:
函数说明
- 返回值: 如果成功,返回指向
str的指针。如果发生错误或到达文件末尾时还未读取任何字符,则返回NULL。 - 效果: 读取的字符串(不包含换行符)会被存储在
str指向的数组中,并在末尾自动添加空字符\0作为字符串结束标志。
实例
让我们通过例子来掌握 gets() 的用法。
示例 1:基础用法 - 读取字符串
实例
#include <stdio.h>
int main()
{
char str[50];
printf("请输入一个字符串:");
gets(str);
printf("您输入的字符串是:%s", str);
return(0);
}
int main()
{
char str[50];
printf("请输入一个字符串:");
gets(str);
printf("您输入的字符串是:%s", str);
return(0);
}
运行结果预期:
请输入一个字符串:runoob 您输入的字符串是:runoob
代码解析:
#include <stdio.h>是使用gets()函数的前提。char str[50];定义了一个长度为 50 的字符数组,用于存储输入的字符串。gets(str);从标准输入读取一行字符串,并存储到str中。printf("您输入的字符串是:%s", str);使用%s格式化符输出字符串。
示例 2:处理返回值为 NULL 的情况
在实际编程中,应该检查 gets() 的返回值,以处理可能的错误。
实例
#include <stdio.h>
int main()
{
char str[100];
char *result;
printf("请输入一些内容(输入 Ctrl+D 可结束):\n");
result = gets(str);
if (result != NULL) {
printf("成功读取,内容是:\n%s\n", str);
} else {
printf("读取失败或已到达文件末尾!\n");
}
return(0);
}
int main()
{
char str[100];
char *result;
printf("请输入一些内容(输入 Ctrl+D 可结束):\n");
result = gets(str);
if (result != NULL) {
printf("成功读取,内容是:\n%s\n", str);
} else {
printf("读取失败或已到达文件末尾!\n");
}
return(0);
}
代码解析:
gets()返回指向同一字符串的指针,如果失败则返回NULL。- 当用户按下 Ctrl+D(Linux/Mac)或 Ctrl+Z(Windows)时,会触发文件结束条件,
gets()返回NULL。 - 在实际项目中,建议使用更安全的
fgets()替代gets()。
示例 3:gets() 的安全问题(⚠️ 演示危险操作)
下面的例子展示了为什么 gets() 是不安全的。
实例
#include <stdio.h>
int main()
{
// 注意:这个例子很危险,仅用于演示!
char buffer[10];
printf("请输入一个较长的字符串(超过10个字符):\n");
gets(buffer); // 没有边界检查,可能导致缓冲区溢出
printf("您输入的是:%s\n", buffer);
return(0);
}
int main()
{
// 注意:这个例子很危险,仅用于演示!
char buffer[10];
printf("请输入一个较长的字符串(超过10个字符):\n");
gets(buffer); // 没有边界检查,可能导致缓冲区溢出
printf("您输入的是:%s\n", buffer);
return(0);
}
代码解析:
buffer[10]只分配了 10 个字节的空间。- 如果用户输入的字符串超过 9 个字符(加上结尾的
\0),就会发生缓冲区溢出,可能覆盖相邻的内存区域。 - 这会被攻击者利用来执行恶意代码,因此
gets()在 C99 标准中已被标记为废弃,在 C11 标准中更是被移除。
更好的替代方案:fgets()
强烈建议使用 fgets() 代替 gets(),因为它可以指定缓冲区大小。
实例
#include <stdio.h>
int main()
{
char str[50];
printf("请输入一个字符串:");
// fgets(缓冲区, 缓冲区大小, 文件流)
fgets(str, sizeof(str), stdin);
// 移除 fgets 读取的换行符
// 方法:查找换行符并替换为空字符
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] == '\n') {
str[i] = '\0';
break;
}
}
printf("您输入的字符串是:%s\n", str);
return(0);
}
int main()
{
char str[50];
printf("请输入一个字符串:");
// fgets(缓冲区, 缓冲区大小, 文件流)
fgets(str, sizeof(str), stdin);
// 移除 fgets 读取的换行符
// 方法:查找换行符并替换为空字符
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] == '\n') {
str[i] = '\0';
break;
}
}
printf("您输入的字符串是:%s\n", str);
return(0);
}
fgets() 的优势:
- 可以指定最大读取字符数,防止缓冲区溢出。
- 会在字符串末尾保留换行符(如需要可手动移除)。
- 可以指定输入来源(标准输入、文件等)。

C 标准库 - <stdio.h>