从文件中读取矩阵时的std :: copy问题

时间:2009-11-23 03:26:08

标签: c++ stream

我不知道为什么整个矩阵都存储在第一行本身。如果有N行,循环实际上会被调用N次。

这是matrix.dat

5
1 2 3
1 2 0 100
3 4 0
5 6 -1
0 9 10 11

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

int main() {

    std::vector<std::vector<int> > matrix;
    std::ifstream infile("matrix.dat");
    int num_rows;
    infile>>num_rows;

    //If there are 5 rows in the matrix, this loops DOES run 5 times.
    for(int i=0;i<num_rows;i++){
            matrix.push_back(std::vector<int>());
            std::copy(
                            std::istream_iterator<int>(infile),
                            std::istream_iterator<int>(),
                            std::back_inserter(matrix[i])
                            );
    }

    // Printing the size of matrix. This correctly prints the value of num_rows
    std::cout<<matrix.size()<<std::endl;

    // Printing just 1st row, but that contains the entire matrix.
    // Seems like copy always happens to matrix[0] only.

    for(int j=0;j<matrix[0].size();j++)
        std::cout<<matrix[0][j]<<" ";

}

3 个答案:

答案 0 :(得分:3)

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

int main()
{

    std::vector< std::vector< int > > matrix;
    std::ifstream infile( "matrix.dat" );

    std::string s;
    while( std::getline( infile, s ) )
    {
        std::string token;
        std::vector< int > tokenisedLine;
        std::istringstream line(s);
        while( std::getline( line, token, ' ' ) )
            tokenisedLine.push_back( atoi( token.c_str() ) );
        matrix.push_back( tokenisedLine );
    }

    return 0;
}

这段代码应该完成你所追求的目标,但是它有点慢,复制和创建所有临时对象。但对于像你的例子这样的小文件,这样会很好。

它使用您的测试数据为我编译和工作。

你可以看到它第一次使用getline两次是基于\ n char分割行,然后我们使用空格char再次使用它。因此,在使用此代码时,您需要使用空格来分隔元素。

然后,一旦我们将令牌作为字符串,我们使用atoi将其转换为int。

HTH。

答案 1 :(得分:1)

std::istream_iterator<int>()表示文件结束。因此,您的复制操作会将文件的全部内容复制到matrix[0]

答案 2 :(得分:1)

您应该使用getline将输入文件拆分为每行的单独字符串。从那里,您可以在该行周围构建istringstream并使用该行解析行。