如何将文件读取为vector<vector<double>>?

Posted

技术标签:

【中文标题】如何将文件读取为vector<vector<double>>?【英文标题】:How to read file as vector<vector<double>>? 【发布时间】:2015-08-24 07:33:43 【问题描述】:

我有这样的数据

4.0 0.8
4.1 0.7
4.4 1.1
3.9 1.2
4.0 1.0

我的程序已经写好了

#include <string>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

int main() 
vector<double> v;
ifstream in("primer.dat");
double word;
while(in >> word)
v.push_back(word);
for(int i = 0; i < v.size(); i++)
cout << v[i] << endl;

但现在我已经意识到,为了在我的代码中进行进一步的计算,我需要数据为 (vector &lt;vector&gt; double)。我不想重塑向量。是否可以将数据读取为向量的向量?

【问题讨论】:

“不要重塑矢量”是什么意思? 对于初学者来说,你需要一个 vector> 还是一个 vector 因为你实际上两者都说。另外,重塑矢量是什么意思...对我来说,您似乎只是从文件中读取,然后用“ ”字符分割每一行以创建矢量... @VladfromMoscow 我可以将其读取为矢量,可以使用重新解释演员表,但这会使事情变得复杂。 @LBesancon 是的,我需要矢量>。 @RichardRublev 不确定我理解您的意思,但请查看我的回答可能会有所帮助 【参考方案1】:

试试下面的

#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <sstream>
#include <string>

int main()

    std::vector<std::vector<double>> v;
    std::ifstream in( "primer.dat" );
    std::string record;

    while ( std::getline( in, record ) )
    
        std::istringstream is( record );
        std::vector<double> row( ( std::istream_iterator<double>( is ) ),
                                 std::istream_iterator<double>() );
        v.push_back( row );
    

    for ( const auto &row : v )
    
        for ( double x : row ) std::cout << x << ' ';
        std::cout << std::endl;
            
    

【讨论】:

@Garg Ankit 谢谢。:) @Richard Rublev 完全没有。我还添加了一个 sn-p 来输出向量。 另一种不错的方式,绝对值得赞:)【参考方案2】:

不确定我是否完全理解你的意思,但如果我这样做了,这段代码应该可以正常工作:

#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>

using namespace std;

std::vector<std::string> split(const std::string& str, char sep)
    
        std::vector<std::string> result;
        std::istringstream iss(str);
        std::string sub;
        while (std::getline(iss, sub, sep))
            result.push_back(sub);
        return result;
    

int main() 
    vector<vector<double> >  completeVector ;
    ifstream in("primer.dat");
    string word;
    while(in >> word)
        std::vector<std::string> splitS = split(word, ' ');
        std::vector<double> line ;
        for(int i = 0 ; i < splitS.size() ; i++)
            line.push_back(stod(splitS[i]));
        
        completeVector.push_back(line);
    

// For printing out the result
    for(int i = 0 ; i < completeVector.size() ; i++)
        std::vector<double> tmp = completeVector[i];
        for(int j = 0 ; j < tmp.size() ; j++)
            std::cout << tmp[j] << std::endl ;
        
       

它可以肯定地编译并且它应该具有您正在寻找的行为。 如果它没有让我在 cmets 中知道。

【讨论】:

可以使用strtok(),而不是实现自己的split():cplusplus.com/reference/cstring/strtok 完全正确,但我只是在一个文件中定义了我自己的函数,在这里粘贴它就像使用 strtok() 一样简单,但你完全正确。 使用库方法总是好的,因为它会使解决方案不易出错。 当然,我完全不否认这一点,正如我之前所说的那样,你是对的。 OP 可以使用他想要的任何东西,两种解决方案都可以正常工作,而且问题并不是真正的 split() 部分。使用这个 split 函数对我来说更方便,因为它直接使用 std::string 并返回 std::string 而不是 char*。 @GargAnkit 不好的建议。也根本不需要拆分,while(in &gt;&gt; word) 已经去除了所有空格。【参考方案3】:
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

int main() 
  vector<vector<double>> v;
  ifstream in("primer.dat");
  string line;
  while(std::getline(in, line))
  
    v.push_back(vector<double>());
    stringstream ss(line);
    double word;
    while(ss >> word)
    
      v.back().push_back(word);
    
  
  for(int i = 0; i < v.size(); i++)
  
    for(int j = 0; j < v[i].size(); j++)
    
      cout << v[i][j] << ' ';
    
    cout << endl;
  


【讨论】:

以上是关于如何将文件读取为vector<vector<double>>?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用文件存储从 xml 文件中读取矢量<vector<Point3f>>

bug将int文件读入vector

如何将 vector<Chunk*> 读/写为内存映射文件?

从文件中读取存入vector的问题

vector 中如何修改某一个元素的值?

c++ io 库将文件内容读入到vector对象