c - 读取文件时出错 "fgetc"(溢出)

标签 c file io c11

我正在使用此代码来读取文件:

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 ?或者有没有办法通过使用 ftellfseek 来确定当前行的长度?

最佳答案

代码不会返回指向字符串的指针。

返回的缓冲区中没有空字符,因此调用代码缺乏知道分配的内存长度的能力。这肯定会导致调用代码出错。

重新分配时,加1。

// buffer = realloc(buffer, ct * sizeof(uint8_t*));
//                                          v--- no star
buffer = realloc(buffer, ct * sizeof(uint8_t ) + 1);
buffer[ct] = '\0';

// or better
size_t ct = 0;
...
buffer = realloc(buffer, sizeof *buffer * (ct + 1));
buffer[ct] = '\0';
<小时/>

Is there any way to dynamically change the size of the array allocated memory depending on the the current iteration without always using realloc?

数组大小无法更改。要动态更改分配的内存大小需要realloc()。注意:所需的内存量可以在内存分配调用之前确定。

or is there an way to determine how long the current line is by using ftell and fseek?

像这段代码一样,您已经找到了当前行长度的上限。 ftellfseek 未定位行尾。

代码可以使用fscanf(file, "%*[^\n]");“寻找”到行尾,或者使用下面的fgetc(file).

关于c - 读取文件时出错 "fgetc"(溢出),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41660675/

相关文章:

c - 将可选参数传递到 C execlp() 时出现问题

c++ - 是否保证标准输出在退出前自动刷新?它是如何工作的?

c# - 通过网络复制文件(需要身份验证)

php - 是否有任何现有服务可通过浏览器上传巨大的视频文件 (~5gb)?

C++:可以在多个文件中调用静态变量吗?

c - 使用带有附加字符的 printf() 进行右对齐

java 。将字符串附加到文件,以奇怪的输出结束

c++ - 读取文本文件中的多行并写入另一个文本文件

C# 异步/等待 I/O 绑定(bind)与 CPU 绑定(bind)操作

haskell - 无法写入句柄