我之前question的后续问题已经得到了完美答复。为了快速回顾一下,我在创建一个拥有巨大数组的类时遇到了麻烦(堆栈溢出错误)。在答案中,一些用户建议我改用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(无论出于何种原因),并且访问vector元素会导致出现向量边界的立即崩溃。
那么我该怎样做才能做到这一点?我曾经读过某个地方,我可以简单地使用“旧”方法,然后将数组读入矢量,但这似乎首先打败了使用矢量的目的。
答案 0 :(得分:5)
fread()
读取您的文件二进制,而ifstream_iterator
尝试提取格式化的整体(如42
)。
您想要resize
vector
并使用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));
答案 1 :(得分:3)
如果你正在使用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]));