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

使用fgets()按16字节分块读取至换行符的问题及合并需求

问题解决方案

一、解决fgets按换行分割读取的问题

fgets本身会在遇到\n时停止读取,但你的问题出在分块大小设置与fgets参数的配合上:fgets的第二个参数是「最大读取字节数(包含终止符\0)」,你当前定义BUF_SIZE=16却传入BUF_SIZE+1,导致每次最多读16个字符(含\0),当单行内容超过15个有效字符时,fgets会直接截断,无法识别换行并停止。

要实现「遇\n即停止读取、每次分块最多读16字节、总读取不超128字节」,需要手动检查读取内容中是否包含换行符,核心逻辑:

  • 每次读取后,用strchr查找\n,存在则说明当前行读取完成,可单独处理
  • 若不存在换行符,继续读取下一块,但需监控总读取字节数不超上限

二、合并读取片段到char*变量

预先分配一个128字节的总缓冲区(含终止符),用变量跟踪已使用字节数,每次读取后将分块内容追加到总缓冲区,同时避免溢出。

完整修正代码

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

#define CHUNK_SIZE 16   // 每次分块读取的最大有效字节数(不含'\0')
#define MAX_TOTAL 128   // 最大总读取字节数(含'\0')

int main() {
    // 分配分块缓冲区:CHUNK_SIZE+1 用于存储终止符'\0'
    char *chunk_buf = malloc(sizeof(char) * (CHUNK_SIZE + 1));
    // 分配总缓冲区:用calloc初始化全0,避免垃圾数据
    char *total_buf = calloc(MAX_TOTAL, sizeof(char));
    if (!chunk_buf || !total_buf) {
        perror("内存分配失败");
        return 1;
    }

    size_t total_used = 0; // 记录总缓冲区已使用字节数(不含'\0')

    while (total_used < MAX_TOTAL - 1) { // 预留一个字节给终止符
        // fgets最多读取CHUNK_SIZE个有效字符(第二个参数为CHUNK_SIZE+1)
        if (!fgets(chunk_buf, CHUNK_SIZE + 1, stdin)) {
            break; // 读取结束或出错
        }

        size_t chunk_len = strlen(chunk_buf);
        // 检查是否超过总容量上限,超出则截断
        if (total_used + chunk_len >= MAX_TOTAL) {
            chunk_len = MAX_TOTAL - total_used - 1;
            chunk_buf[chunk_len] = '\0';
        }

        // 将分块内容追加到总缓冲区
        strncat(total_buf, chunk_buf, chunk_len);
        total_used += chunk_len;

        // 检测换行符,处理完整行
        char *newline_pos = strchr(chunk_buf, '\n');
        if (newline_pos != NULL) {
            printf("完整行:%.*s", (int)(newline_pos - chunk_buf + 1), chunk_buf);
        }
    }

    // 打印合并后的全部内容
    printf("\n合并后总内容:\n%s", total_buf);

    free(chunk_buf);
    free(total_buf);
    return 0;
}

关键说明

  • 换行检测:通过strchr定位\n,一旦找到即可判定当前行读取完成,单独处理该行
  • 分块控制:fgets第二个参数设为CHUNK_SIZE+1,确保每次最多读取16个有效字符(含\n),自动添加终止符
  • 容量限制:用total_used跟踪已用字节数,保证总内容不超过128字节(含终止符)
  • 内存安全:用calloc初始化总缓冲区,strncat替代strcat避免溢出

测试验证

执行echo -e "ls -l\nls -l\nls -l" | ./mycode(需加-e让echo解析转义字符),会输出3行完整的ls -l,合并后的总内容也包含这三行。

内容的提问来源于stack exchange,提问作者Joaquín Ayala Filardi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 01:25:37