fgets 函数 - 安全的字符串输入
fgets 函数从指定的流(如 stdin,即标准输入,通常是键盘)中读取一行字符,并将其存储在提供的缓冲区中,它被认为是比 gets 函数更安全的选择。

(图片来源网络,侵删)
函数原型
char *fgets(char *str, int n, FILE *stream);
参数说明
char *str: 这是一个字符指针(或字符数组),用于存储从流中读取的字符串。fgets会将读取的内容放入这个str指向的内存区域。int n: 这是一个整数,表示要读取的最大字符数(包括结尾的空字符\0)。这是fgets安全性的关键,它最多会读取n-1个字符,然后自动在第n个位置添加一个空字符\0来结束字符串,从而防止缓冲区溢出。FILE *stream: 这是一个指向FILE对象的指针,指明了从哪里读取数据。stdin: 从标准输入(键盘)读取。stdin是在<stdio.h>中定义的指针。
返回值
- 成功时:返回指向
str的指针。 - 到达文件末尾或发生读取错误时:返回
NULL(空指针)。
工作原理与特点
- 读取换行符:
fgets会读取并存储输入行中的换行符\n(如果缓冲区足够大且行长度不超过n-1),你输入 "hello world",fgets会将 "hello world\n\0" 存入缓冲区。 - 缓冲区限制:如果输入的行太长(超过了
n-1个字符),fgets只会读取前n-1个字符,并在第n个位置添加\0,剩余的字符会留在输入流中,成为下一次输入操作的输入。 - 安全性:由于
n参数限制了读取的字符数,fgets不会像gets那样导致缓冲区溢出,从而更安全。
示例代码
#include <stdio.h>
#define BUFFER_SIZE 100
int main() {
char name[BUFFER_SIZE];
printf("请输入你的名字: ");
// 从标准输入读取最多 BUFFER_SIZE - 1 个字符
// 如果用户输入 "Alice",name 将会是 "Alice\n\0"
// 如果用户输入 "A very very very long name...",name 将会是 "A very very very long na\0"
// 剩下的 "me..." 会留在输入缓冲区中。
if (fgets(name, BUFFER_SIZE, stdin) != NULL) {
printf("你输入的名字是: %s", name); // puts(name) 也可以
} else {
printf("读取输入失败,\n");
}
return 0;
}
如何去除 fgets 读取的换行符 \n?
这是一个非常常见的需求,因为 printf 会原样输出 \n,导致输出多出一个空行。
#include <stdio.h>
#include <string.h> // 用于 strlen
#define BUFFER_SIZE 100
int main() {
char name[BUFFER_SIZE];
printf("请输入你的名字: ");
fgets(name, BUFFER_SIZE, stdin);
// 检查字符串中是否有换行符
size_t len = strlen(name);
if (len > 0 && name[len - 1] == '\n') {
// 将换行符替换为字符串结束符 \0
name[len - 1] = '\0';
}
printf("你好, %s!\n", name); // 这时输出就不会有多余的空行了
return 0;
}
puts 函数 - 简单的字符串输出
puts 函数用于将一个字符串输出到标准输出(stdout,通常是屏幕),并在字符串的末尾自动添加一个换行符 \n。
函数原型
int puts(const char *str);
参数说明
const char *str: 这是一个指向要输出的字符串的常量字符指针。puts会从这个位置开始,逐个字符输出,直到遇到空字符\0为止。
返回值
- 成功时:返回一个非负整数。
- 失败时:返回
EOF(End of File,通常定义为 -1)。
工作原理与特点
- 自动添加换行符:
puts的核心功能是在输出完字符串后,自动在末尾输出一个换行符,这意味着你不需要像printf那样在字符串后面手动加\n。 - 不能格式化输出:
puts只能输出字符串,如果你需要输出数字、变量或者格式化的文本,你必须使用printf。 - 不会输出换行符本身:如果字符串的末尾恰好有一个
\n(比如刚被fgets读取过),puts会输出这个\n,然后再加上自己的\n,导致输出两个换行符(即一个空行)。
示例代码
#include <stdio.h>
int main() {
char message[] = "Hello, C World!";
// 输出 "Hello, C World!" 并自动换行
puts(message);
// 输出一个空行,因为 puts 会自动添加 \n
puts("");
// 输出 "This is a new line." 并自动换行
puts("This is a new line.");
return 0;
}
fgets 和 puts 的配合使用
这两个函数经常一起使用,实现一个简单的“回显”程序:从键盘读取一行,然后原样打印到屏幕上。

(图片来源网络,侵删)
#include <stdio.h>
#include <string.h>
#define MAX_LEN 256
int main() {
char buffer[MAX_LEN];
printf("请输入一行文字 (按回车结束):\n");
// 1. 使用 fgets 从标准输入读取一行
if (fgets(buffer, MAX_LEN, stdin) != NULL) {
// 2. 去掉 fgets 读取的换行符
size_t len = strlen(buffer);
if (len > 0 && buffer[len - 1] == '\n') {
buffer[len - 1] = '\0';
}
// 3. 使用 puts 输出处理后的字符串
puts("你输入的文字是:");
puts(buffer);
} else {
puts("读取输入时发生错误。");
}
return 0;
}
运行示例:
请输入一行文字 (按回车结束):
This is a test.
你输入的文字是:
This is a test.
总结与对比
| 特性 | fgets |
puts |
|---|---|---|
| 功能 | 从流中读取一行字符 | 向标准输出输出一行字符串 |
| 安全性 | 高,有 n 参数限制读取长度,防止溢出 |
不涉及输入,本身是安全的 |
| 输入/输出 | 输入函数 | 输出函数 |
| 换行符处理 | 会读取并存储 \n(如果缓冲区足够) |
会自动添加 一个 \n 到输出末尾 |
| 主要用途 | 安全地从键盘或文件读取字符串 | 简单地输出字符串并自动换行 |
| 灵活性 | 可以指定输入源(stdin, FILE*) |
只能输出到标准输出 |
| 格式化 | 不支持 | 不支持 |
核心记忆点:
fgets是安全的gets:用它来从键盘读字符串,永远记住指定缓冲区大小。puts是带自动换行的printf:用它来简单地打印一个字符串,省去自己写\n的麻烦。- 组合使用:
fgets+puts是 C 语言中最经典的“输入-输出”组合之一,使用fgets后,如果想去掉末尾的换行符,记得用strlen检查并替换。

(图片来源网络,侵删)
