fgets在c语言中怎么用(通俗易懂,带实例)
fgets 是 C 标准库 <stdio.h> 提供的“行输入”函数,原型:
char *fgets(char *str, int n, FILE *stream);
它从指定流最多读取 n-1 个字符,遇到换行或 EOF 提前结束,并在 str 末尾自动补 '\0'。成功返回 str,失败或读到 EOF 返回 NULL。
相比 scanf("%s") 与 gets,fgets 提供“长度安全”保证:通过第 2 参数防止缓冲区溢出;同时保留 '\n',便于后续处理。C11 已删除 gets,fgets 成为行输入首选。
fgets基本语法
char buf[100]; fgets(buf, sizeof(buf), stdin); /* 三要素:目标、容量、来源 */
- buf:存放结果的字符数组。
- n:数组大小,函数最多读 n-1 字符。
- stream:FILE * 指针,stdin 代表键盘,文件指针亦可。
#include <stdio.h> int main(void) { char line[64]; printf("输入一行文字:"); if (fgets(line, sizeof(line), stdin)) /* 安全读取 */ printf("你写了:%s", line); return 0; }
运行:
输入:hello world↵
输出:你写了:hello world(含换行)
fgets应用场景
1) 如何处理末尾的换行符
fgets 把用户按下的 Enter 键('\n')也存入数组。多数场景需要去掉它:
line[strcspn(line, "\n")] = '\0'; /* 通用裁剪 */
strcspn 返回 '\n' 的下标,若没找到则返回字符串长度,代码同样安全。
2) 循环读取多行直到 EOF
#include <stdio.h> int main(void) { char buf[128]; while (fgets(buf, sizeof(buf), stdin)) { /* 返回 NULL 时结束 */ buf[strcspn(buf, "\n")] = '\0'; /* 去换行 */ puts(buf); /* 处理逻辑 */ } return 0; }
在 Linux 终端用 Ctrl+D、Windows 用 Ctrl+Z 产生 EOF,循环结束。
3) 与 sscanf 搭配解析
先整行读入,再扫描,可避免 scanf 遗留换行问题:
char line[64]; int a, b; fgets(line, sizeof(line), stdin); /* 读一行 */ if (sscanf(line, "%d%d", &a, &b) == 2) /* 解析两个整数 */ printf("a=%d b=%d\n", a, b);
4) 安全边界演示:防止溢出
#include <stdio.h> int main(void) { char small[8]; printf("请输入超长文本:"); fgets(small, sizeof(small), stdin); /* 只读 7 字符 + '\0' */ printf("缓冲区内容:%s\n", small); return 0; }
输入:1234567890↵
输出:缓冲区内容:1234567(剩余字符留在输入流,可被下次读取)
5) 读取文件中的行
#include <stdio.h> int main(void) { FILE *fp = fopen("test.txt", "r"); if (!fp) { perror("fopen"); return 1; } char buf[256]; int cnt = 0; while (fgets(buf, sizeof(buf), fp)) { /* 逐行读文件 */ ++cnt; printf("%3d: %s", cnt, buf); /* 显示行号 */ } fclose(fp); return 0; }
常见错误与排查
- 忘记检测 NULL 返回值,导致 EOF 时仍处理旧数据。
- 数组大小填错,如 fgets(buf, 100, stdin) 而 buf 只有 50 字节。
- 误用 sizeof 指针:传动态分配内存时,应写实际长度而非 sizeof(char*)。

浙公网安备 33010602011771号