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

从文本文件读取char[]后,如何获取实际读取的缓冲区大小?

优化char*缓冲区读取长度的方案

嘿,针对你的需求(必须用char*、逐行读取、超长行拆分),我给你几个比手动循环找换行符更高效简洁的方案,同时修正你当前代码里的小问题:

先说说你当前代码的小问题

你的limpiarBuffer函数里,return int(strlen(buffer) - 1)是错误的——如果一行没有换行符(比如超长行被截断、或者文件最后一行没有换行),strlen(buffer)就是实际读取的字符数,减1会少算一个字符。另外,循环里每次调用strlen会重复遍历整个字符串,效率很低。


方案一:用标准库函数strchr快速定位换行符

strchr是C标准库提供的高效函数,能直接找到字符在字符串中的位置,代码简洁且性能优秀:

#include <cstring> // 或者 <string.h>,取决于你的编译环境

int Gestor::obtenerTamanoBuffer(char* buffer) {
    // 查找换行符的位置
    char* newlinePos = strchr(buffer, '\n');
    if (newlinePos != nullptr) {
        // 换行符到缓冲区开头的偏移量,就是实际读取的有效字符数(不含换行)
        return newlinePos - buffer;
    } else {
        // 没找到换行符,说明要么是行尾,要么是缓冲区满了,返回整个字符串长度
        return strlen(buffer);
    }
}

为什么这个方案更好?

  • 代码可读性强,逻辑清晰;
  • strchr是编译器优化过的库函数,比手动写循环效率更高;
  • 准确处理所有情况:带换行的行、超长截断的行、无换行的文件尾行。

方案二:手动一次遍历(适合不想用库函数的场景)

如果课程要求不能用strchr,可以手动遍历一次字符串,避免重复调用strlen:

int Gestor::obtenerTamanoBuffer(char* buffer) {
    int len = 0;
    // 遍历到字符串结束或找到换行符就停止
    while (buffer[len] != '\0' && buffer[len] != '\n') {
        len++;
    }
    return len;
}

这个方案的优势:

  • 只遍历一次字符串,比你原来的循环(每次迭代都调用strlen)效率高很多;
  • 逻辑简单,不容易出错。

额外的读取逻辑优化

你当前用!feof(fichero)判断的写法不够稳妥,feof只有在尝试读取后才会设置标志位,更可靠的写法是直接用fgets的返回值判断循环:

char *buffer = new char[255];
int tamanio;

// 直接用fgets的返回值判断:成功读取到内容就进入循环
while (fgets(buffer, 254, fichero) != NULL) {
    tamanio = obtenerTamanoBuffer(buffer);
    printf("Tamanio buffer: %i \n", tamanio);
    // printarCadena(buffer);
}

// 循环结束后,可以判断是文件结束还是读取错误
if (ferror(fichero)) {
    // 处理读取错误的逻辑,比如打印错误信息
    perror("Error al leer el fichero");
}

这样既可以自动处理超长行拆分(fgets会每次读取253个字符,直到读完整个长行),也能准确判断读取状态。

内容的提问来源于stack exchange,提问作者Luis Bote

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:04:35