2013-02-28 98 views
2

后续问题question我已经完全回答了。为了快速回顾一下,我无法创建一个拥有巨大数组的类(堆栈溢出错误)。在答案中,一些用户建议我使用std :: vector来代替。如何在二进制文件上使用fread()将数据读入std :: vector?

功能在数据读取如下:

Test() 
{ 
    memset(myarray, 0, sizeof(myarray)); 
    FILE* fstr = fopen("myfile.dat", "rb"); 
    size_t success= fread(myarray, sizeof(myarray), 1, fstr); 
    fclose(fstr); 
} 

的myArray的看起来像这样:

int myarray[45000000]; 

我的问题是:我怎么能看这种成最好:

std::vector<int> myvector; 

我搜索谷歌,并找到了多个答案,通常指向下面的代码:

std::ifstream input("myfile.dat", std::ios::in | std::ifstream::binary); 
std::copy(std::istream_iterator<int>(input), 
    std::istream_iterator<int>(), 
    std::back_inserter(myvector)); 

实施之后,并调用myvector.size()时,我得到16(无论何种原因),并访问向量元素会导致立即死机走出去的矢量界。

那么我该怎么做才能做到这一点?我曾经在某处读过我可以简单地使用“旧”方法,然后将数组读入向量中,但这似乎无法摆脱首先使用该向量的目的。

+1

'istream_iterator'格式化输入。如果你的文件是二进制格式,那不是你想要的。 – jrok 2013-02-28 19:11:02

+0

@MichaelDorgan:根本不读这个问题的方法。 @MarkAnderson:'std :: istream_iterator '_formatted_读取,旧'fread'是_unformatted_读取。您需要对矢量进行无格式读取。 – 2013-02-28 19:11:45

+0

然后走开我的评论 - 我更多的C家伙反正:) – 2013-02-28 19:13:17

回答

5

fread()读取您的文件二进制,而ifstream_iterator尝试提取格式化整数(如42)。

你想resizevector,并使用input.read(...)代替:

const size_t size = 45000000; // change this to the appropriate value 
std::vector<char> myvector(size, 0); 
std::ifstream input("myfile.dat", std::ios::in | std::ifstream::binary); 
input.read(&myvector[0], myvector.size()); 

请注意,您需要使用std::vector<char>因为read预计第一个参数是一个char *。如果你正确地投的类型可以使用其他类型的T

input.read(reinterpret_cast<char*>(&myvector[0]), myvector.size() * sizeof(T)); 
+0

谢谢!它像一个魅力一样工作! – 2013-02-28 19:36:26

2

如果您正在使用C++,你应该尽量避免使用C FILE的API都在一起 - 所以你在正确的轨道上。你遇到的问题是,istream_iterator以文本形式读取输入,而不是二进制 - 它需要ASCII数字。这反过来:

std::vector<int> vec(45000000); 

std::filebuf fb; 
fb.open("myfile.dat", std::ios_base::in | std::ios_base::binary); 
fb.sgetn((char*)&vec[0], vec.size() * sizeof(vec[0])); 
相关问题