我有一个文本文件,我想读到一个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()”命令,我也不知道该如何处理这个问题。但也许这是必要的?任何帮助都很感激。
1条答案
按热度按时间2skhul331#
您应该经常检查I/O函数的返回值。一个充分的理由是检查错误,但是当
fread
存储的字节可能比读取的字节少(* 例如,在Windows上,文件以默认文本模式打开),返回值是如何知道存储了多少以及使用多少缓冲区。缓冲区末尾的数据明显重复,这证明了以二进制模式阅读缓冲区,然后将字符移回以隐藏回车的实现策略。这对于正确的程序来说并不重要,但是标准库以这种方式使用提供的缓冲区是有意义的。