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*)。
posted @ 2025-11-24 17:41  像风一样的博主  阅读(122)  评论(0)    收藏  举报