带有列的 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&lt;vector&gt;

现在您无需担心尺寸。

添加元素就像

一样简单

std::vector&lt;float&gt; 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::arrays太主流了 @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 向量中的主要内容,如果未能解决你的问题,请参考以下文章

将矩阵加载到 2D 向量 C++

将文本文件读入二维向量。 C++

从文本文件中读取整数并使用 C++ 将它们存储到向量中

带有到 odbc 数据库的列的文本文件

将文本文件中的单个字符存储到向量 C++ 中时的 std::bad_alloc

在 C++ 中创建 OpenCV 矢量并存储到文本文件