带有列的 C++ 文本文件到 2D 向量中
Posted
技术标签:
【中文标题】带有列的 C++ 文本文件到 2D 向量中【英文标题】:C++ text file with columns into 2D vector 【发布时间】:2013-12-09 12:43:35 【问题描述】:我有一个包含值的文本文件,我想将它们放入二维向量中。
我可以用数组做到这一点,但我不知道如何用向量做到这一点。
向量大小应该像我事先不知道的vector2D[nColumns][nLines]。我最多可以在文本文件中有列数,但不能有行数。 列数可能不同,从一个 .txt 文件到另一个。
.txt 示例:
189.53 -1.6700 58.550 33.780 58.867
190.13 -3.4700 56.970 42.190 75.546
190.73 -1.3000 62.360 34.640 56.456
191.33 -1.7600 54.770 35.250 65.470
191.93 -8.7500 58.410 33.900 63.505
使用数组我这样做:
//------ Declares Array for values ------//
const int nCol = countCols; // read from file
float values[nCol][nLin];
// Fill Array with '-1'
for (int c = 0; c < nCol; c++)
for (int l = 0; l < nLin; l++)
values[c][l] = -1;
// reads file to end of *file*, not line
while (!inFile.eof())
for (int y = 0; y < nLin; y++)
for (int i = 0; i < nCol; i++)
inFile >> values[i][y];
i = 0;
【问题讨论】:
while (!inFile.eof())
是错误的。别这样!
@LightnessRacesinOrbit 应该改用什么?
【参考方案1】:
而不是使用
float values[nCol][nLin];
使用
std::vector<std::vector<float>> v;
为此,您必须#include<vector>
。
现在您无需担心尺寸。
添加元素就像
一样简单std::vector<float> f; f.push_back(7.5); v.push_back(f);
也不要在流上使用.eof()
,因为它直到到达末尾才会设置它,因此它会尝试读取文件的末尾。
while(!inFile.eof())
应该是
while (inFile >> values[i][y]) // returns true as long as it reads in data to values[x][y]
注意:除了vector
,您还可以使用std::array
,这显然是切片面包后最好的东西。
【讨论】:
如果列数已知,并且在整个数据集中保持不变,则可以通过在循环外定义单个向量来优化此方法,将其大小重新调整为列数,然后在循环中反复为其设置值,并在每次迭代结束时将其推入结果向量中。 但是我应该注意到std::vector
比通常的 C 数组要慢一些。如果 OP 需要最大性能,他应该小心使用std::vector
。
@DNT,因为用std::array
s太主流了
@Axilles [引用需要]。
@BartekBanachewicz 你是什么意思?我不明白。【参考方案2】:
我的建议:
const int nCol = countCols; // read from file
std::vector<std::vector<float>> values; // your entire data-set of values
std::vector<float> line(nCol, -1.0); // create one line of nCol size and fill with -1
// reads file to end of *file*, not line
bool done = false;
while (!done)
for (int i = 0; !done && i < nCol; i++)
done = !(inFile >> line[i]);
values.push_back(line);
现在您的数据集有:
values.size() // number of lines
也可以用数组表示法来处理(除了使用迭代器):
float v = values[i][j];
注意:此代码没有考虑到最后一行可能具有少于 nCol 数据值的事实,因此行向量的末尾将在文件末尾包含错误的值。您可能需要添加代码以在 done 变为 false 时清除行向量的末尾,然后再将其推送到值中。
【讨论】:
我已经尝试过,但图表上仍有一些警告和错误,结果不是我所期望的。我该怎么做: .txt values column 1 -> vector[0][j]; .txt 值第 2 列 -> 向量[1][j]; ... ? 值向量表示数据中的行集合。您在 (0,0) 处的表位于 values[0][0] 处,第 2 行 (56.970) 中的第三个数据项位于 values[1][2] 处。 values 向量的最左侧索引是从零开始的行号,最右侧是您的列号(再次从零开始)。这种表示是行主要的(参考:en.wikipedia.org/wiki/Row-major_order)。这就是您的原始代码从文件中读取值的方式。 'values column 1 -> vector[0][j]' 你的意思是你现在想要你的数据以列为主格式吗? 我想从 values[0][i] 中的第一列中获取 .txt 中的值,从 values[2][i] 中的第三列中获取值...所以值(56.970) 应该在值[2][1] 我也可以继续使用数组,但我需要减小初始大小。是否可以?另外,可以知道一个文件的行数吗? 好的,这似乎是一种以列为主的格式。与它包含的数据相比,std::vector 本身的内存开销很小。层次结构从 _Container_base 类(无数据成员)开始,然后是 _Vector_val 类(包含分配器对象引用),然后是包含 3 个指针(first、last、end)的向量类模板。简而言之,在 64 位系统中的所有 4 个指针/引用是每个向量类实例 8x4 = 32 个字节。在大多数情况下,与包含的数据相比,这是一个非常小的开销。以上是关于带有列的 C++ 文本文件到 2D 向量中的主要内容,如果未能解决你的问题,请参考以下文章