【问题标题】:How to read file as vector<vector<double>>?如何将文件读取为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 不确定我理解您的意思,但请查看我的回答可能会有所帮助

标签: c++ c++11 vector


【解决方案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;
  }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2014-10-11
    相关资源
    最近更新 更多