windows fread正在两次阅读我的文本文件的最后一部分

wn9m85ua  于 2023-05-19  发布在  Windows
关注(0)|答案(1)|浏览(194)

我有一个文本文件,我想读到一个std::vector。如果向量有点太大也没关系,但它似乎在做一件非常奇怪的事情:它复制整个文件,然后复制文件末尾附近的一部分两次并追加它。(我想这可能只是垃圾,但我不知道。
因此,如果文件看起来像这样(这是一个相当大的txt文件):

0kb        100kb       200kb      300kb   
 v          v           v           v
[1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ]

内存中的副本如下所示:

0kb        100kb       200kb      300kb   302kb
 v          v           v           v     v
[1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ TUVW]
                              ^^^^ this section is repeated at the end

我不完全确定是什么导致了它,我写的代码来执行这个复制是这样的。

  • 我首先使用stat来获得可以容纳文件的大小(以字节为单位)。这可能会因为窗口如何行结尾而变得更大。
  • 我分配我的记忆。
  • 我使用fread()将文件一次性复制到矢量中。
void copyFile(std::vector<char> & output, const char * filename) {
    output.clear();
    FILE * file = fopen(filename, "r");
    if (!file)
        return;
    {
        struct stat statBuffer;
        stat(filename, &statBuffer);
        output.resize(statBuffer.st_size + 1);
        fread(output.data(), 1, statBuffer.st_size, file);
        output[statBuffer.st_size] = 0;  // make sure it's null terminated
    }
    fclose(file);
}

我的理论是fread()阅读过了文件的结尾,复制了垃圾?我希望fread()从文件读取n字节,但也许这个参数指的是n字节 * 输出 *?这些值会有所不同,因为它为每个换行符阅读2个字节,然后输出1个字节。但我找不到任何关于这方面的信息。如果不把读操作分解成一堆非常小的“getline()”命令,我也不知道该如何处理这个问题。但也许这是必要的?任何帮助都很感激。

2skhul33

2skhul331#

您应该经常检查I/O函数的返回值。一个充分的理由是检查错误,但是当fread存储的字节可能比读取的字节少(* 例如,在Windows上,文件以默认文本模式打开),返回值是如何知道存储了多少以及使用多少缓冲区。
缓冲区末尾的数据明显重复,这证明了以二进制模式阅读缓冲区,然后将字符移回以隐藏回车的实现策略。这对于正确的程序来说并不重要,但是标准库以这种方式使用提供的缓冲区是有意义的。

相关问题