使用C ++创建数组,而不必提前知道长度

时间:2014-11-18 01:14:00

标签: c++ arrays

我正在开展一个小程序,以帮助加快我实验室工作的数据分析速度。它应该从文本文件中读取数据,创建一堆包含这些数据的数组然后做一些数学运算。

我遇到的问题是我不知道原始文本文件会有多少行,所以我不知道制作数组有多大。我对C ++很陌生,现在我对动态大小的数组感到不舒服,这里有一些代码

// first determine the length of the file
ifstream dataFile ("xys_data.txt");
const int LENGTH = count(istreambuf_iterator<char>(dataFile), istreambuf_iterator<char>(), '\n'); // counts the number of new lines

// declare vector of type datapoint
dataPoint data[LENGTH];

当我尝试编译时,我得到了错误

expected constant expression
cannot allocate an array of constant size 0
'data' : unknown size

但我还没有确定LENGTH是不变的吗?

任何帮助将不胜感激。

修改

按照几乎所有人的建议,我已经开始使用std :: vector了。我有一个最后一个问题,我有点不稳定。

在第一次尝试该程序时,我定义了一个数据结构:

struct dataPoint
{
  double x; // x values
  double y; // y values
  double s; // sigma values
};

然后,当我从文件中读取数据时,我将其发送到这样的结构

while (!dataFile.eof()) // this loop writes out each row of data to the arrays x, y, s until it reaches the end of the file
{ 
  int j = 0;
  dataFile >> data[j].x >> data[j].y >> data[j].s;
  j++;
}

有没有办法可以用矢量做到这一点?我的第一个想法是定义向量x,y和s,并在循环中用data[j].x替换x,但这不起作用。

3 个答案:

答案 0 :(得分:3)

您说您对动态大小的数组或std::vector感到不舒服。

我担心你必须弄清楚如何在这里感到舒服,因为那正是std::vector的用途。

唯一的另一种选择是使用gcc编译器。 gcc允许您拥有可变大小的数组。它是一个编译器扩展,它不是标准的C或C ++:

void method(size_t n)
{
   dataPoint array[n];

   // Do something with the array.
}

答案 1 :(得分:3)

首先,C ++中内置的数组必须具有编译时的大小。声明LENGTH变量const是不够的。使它成为编译时常量也很重要。您的LENGTH不是编译时常量,因此无法声明大小为LENGTH的数组。这就是编译器试图告诉你的。

当您需要构建一个预先不知道其大小的数组时,您通常至少有三种方法可供选择:

  1. 双遍阅读。进行&#34;干运行&#34;在数据源上确定未来数组的确切大小。分配数组。对数据源进行第二次传递,以使用数据填充数组。

  2. 重新分配。使用可重新分配的数组。分配一些固定大小的数组并用数据填充它。如果阵列被证明太小,请将其重新分配到更大的尺寸并继续填充它。继续阅读并重新分配,直到读完所有数据。

  3. 转换。将数据读入便宜且易于扩展的数据结构(如链接列表),然后将其转换为数组。

  4. 这些方法中的每一种都有自己的优点和缺点,限制和适用范围。

    在您的情况下,您似乎正在尝试使用第一种方法。在处理文件时使用它不是一个好主意。首先,对文件进行两次传递效率不高。其次,在一般情况下,它可能会创建竞争条件:文件可能会在传递之间发生变化。如果您仍想这样做,只需使用std::vector而不是内置数组。

    但是,在您的情况下,我建议使用第二种方法。再次,使用std::vector来存储您的数据。逐行读取数据并逐项将其附加到矢量。载体将根据需要自动重新分配。

答案 2 :(得分:0)

您可以使用C ++容器,例如std::vector,也可以使用dataPoint *data = malloc(LENGTH * sizeof(dataPoint))。在C ++中,使用std::vector可能是更好的做法。

C99有variable-length arrays,但你的问题似乎是C ++。

但真正的问题是,你想要一次性整个文件。除非您使用的是需要数据存储在内存中的库,否则使用fgetc或C ++为此迭代文件的文本可能会更容易。毕竟,你需要在某个时候阅读文本;你也可以省去分配内存的麻烦。