You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

fgets读取字符串后fputs输出换行丢失问题求助

问题分析与解决方案

问题原因

你遇到的核心问题是fgets的读取逻辑:当输入内容长度达到缓冲区上限(比如ID的缓冲区是15字节,最多读14个有效字符加\0)时,fgets不会读取换行符,而是直接截断输入;同时你的FlushInputBuf会把输入缓冲区剩余的内容(包括换行符)清空,导致id数组里没有换行符,最终fputs输出时没有换行,和下一行内容连在一起。

解决方案

要确保每个字段输出后都有换行,最可靠的方式是:

  1. 对每个用fgets读取的字符串,先移除末尾的换行符(如果存在);
  2. 输出时统一使用「标签 + 处理后的字符串 + 换行」的格式;
  3. 优化输入缓冲区清空逻辑,避免不必要的阻塞。

修改后的完整代码

#include <stdio.h>
#include <string.h>

void FlushInputBuf(void)
{
    int c;
    // 清空直到换行或EOF,避免阻塞
    while ((c = getchar()) != '\n' && c != EOF);
}

void strip_newline(char *str)
{
    char *nl = strchr(str, '\n');
    if (nl != NULL) {
        *nl = '\0';
    }
}

int main(void)
{
    FILE *fp = fopen("details.txt", "wt");
    if (fp == NULL)
    {
        puts("File open failed.\n");
        return -1;
    }
    char name[20];
    char id[15];
    char phoneNum[14];

    printf("Enter name: ");
    fgets(name, sizeof(name), stdin);
    strip_newline(name);

    printf("Enter ID: ");
    fgets(id, sizeof(id), stdin);
    strip_newline(id);
    // 仅当输入长度达到缓冲区上限时,才清空剩余输入
    if (strlen(id) == sizeof(id) - 1) {
        FlushInputBuf();
    }

    printf("Enter phone number: ");
    fgets(phoneNum, sizeof(phoneNum), stdin);
    strip_newline(phoneNum);
    // 同样处理手机号的超长输入
    if (strlen(phoneNum) == sizeof(phoneNum) - 1) {
        FlushInputBuf();
    }

    // 统一格式输出,确保每个字段后都有换行
    fprintf(fp, "#Name: %s\n", name);
    fprintf(fp, "#SSID: %s\n", id);
    fprintf(fp, "#Phone number: %s\n", phoneNum);
  
    fclose(fp);

    return 0;
}

关键修改说明

  • strip_newline函数:利用strchr快速找到换行符并替换为\0,确保字符串末尾没有多余的换行;
  • 优化FlushInputBuf:添加EOF判断,避免输入流结束时的无限阻塞;
  • 条件清空缓冲区:只有当读取的字符串长度达到缓冲区最大值时,才清空剩余输入,避免正常输入时的不必要阻塞;
  • 使用fprintf统一输出:直接在格式字符串中加入\n,确保每个字段输出后都有换行,彻底解决格式混乱问题。

内容的提问来源于stack exchange,提问作者Kim Minseo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 00:30:26