【发布时间】:2024-04-14 22:15:01
【问题描述】:
我正在使用此代码读取文件:
char* fs_read_line(FILE* file)
{
if (file == NULL) {
return "CFILEIO: Error while reading the file: Invalid File";
}
long threshold = ftell(file);
fseek(file, 0, SEEK_END);
uint8_t* buffer = calloc(ftell(file)-threshold, sizeof(uint8_t));
if(buffer == NULL)
return;
int8_t _;
fseek(file, threshold, SEEK_SET);
uint32_t ct = 0;
while ((_ = (char)(fgetc(file))) != '\n'
&& _ != '\0' && _ != '\r' && _ != EOF) {
buffer[ct++] = _;
}
buffer = realloc(buffer, sizeof *buffer * (ct + 1));
buffer[ct] = '\0';
return buffer;
}
如果文件太大,我会得到(堆)溢出错误,可能是因为我最初用它包含的字符总数分配文件。
我尝试这样做的另一种方法是在每次迭代后通过 realloc 缓冲区,但这有点不是我想要的方法。
有没有办法根据当前迭代动态改变数组的大小,而不总是 uisng realloc ?或者有没有办法通过使用ftell 和fseek 来确定当前行的长度?
【问题讨论】:
-
您显示的代码无法在 C++ 中编译。请不要添加无关的标签。
-
sizeof(uint8_t*)为您提供指针的大小,而不是单个字节的大小。在uint8_t存在的系统上,这几乎完全可以肯定只有 1。所以你分配文件大小的 4 或 8 倍,然后你不检查分配是否成功。 -
相比
memset,buffer[ct++] = _清晰很多。 -
您的代码也存在一些问题,包括它可能返回一个无法调用
free的字符串字面量指针,并且您没有任何类型的错误检查calloc或realloc来电。无论如何都不需要realloc调用,这很好,因为你用错了。为什么要使用memset来复制单个字节?为什么不使用例如buffer[ct++] = _? -
哦,记住
fgetc返回的是int而不是char。