C ++中的大文件读取错误

时间:2015-10-18 14:49:09

标签: c++ file-io

我需要读取具有这种特定格式的c ++文件:

  

10 5
  1 2 3 4 1 5 1 5 2 1

所有值都用空格分隔。第一行的前两个分别是变量N和M,第二行的所有N值都需要在一个名为S的数组中,大小为N.我编写的代码对这些文件没有问题但是当涉及到数百万的真正大文件时,它不起作用,我需要它来使用它。这是代码

int N,M;
FILE *read = fopen("file.in", "r");
fscanf(read, "%d %d ", &N, &M);
int S[N];
for( i =0; i < N; i++){
    fscanf(read, "%d ", &S[i]);        
}

我应该改变什么?

2 个答案:

答案 0 :(得分:1)

您正在使用可变大小的数组。这不是标准的,并不是所有编译器都支持。如果您的编译器支持它,并且您需要数百万,那么您将耗尽堆栈空间(堆栈溢出)。

或者,您可以将S定义为具有vector<int> S(N);

的向量

答案 1 :(得分:1)

进入百万整数的范围时,存在多个潜在问题:

  • int通常是32位,32位有符号整数的范围是-2 ^ 31到2 ^ 31-1,因此最大值为2,147,483,647。你应该切换到64位积分。

  • 您使用的是int S[N]可变长度数组(VLA),它不是标准C ++(它是标准C99,但是......讨论是否是个好主意) 。但重要的细节是,VLA存储在堆栈中:1百万32位int是4 MB,2百万是8 MB等等...检查您的默认堆栈大小,但它可能是小于8 MB,因此你有一个堆栈溢出(你在正确的网站上寻求帮助!)。

所以,让我们切换到C ++并解决这些问题:

#include <cstdint> // for int64_t
#include <fstream>
#include <vector>

int main(int argc, char* argv[]) {
   std::ifstream stream("data.txt");

   int64_t n = 0, m = 0;
   stream >> n >> m;

   std::vector<int> data;
   for (int64_t c = 0; c != n; ++c) {
       int i = 0;
       stream >> i;
       data.push_back(i);
   }

   // do your best :)
}

首先,我们使用int64_t中的<cstdint>来消除整数溢出问题。其次,我们使用流(输入文件流:ifstream)来避免必须了解与每个整体类型相关联的格式(这是一种痛苦)。第三,我们使用vector来存储我们读取的数据,并消除堆栈溢出问题。