I have a Plain Text matrix file (called q.txt):

1	0	0
0	2	0
0	1	1
0	0	1
1	1	1

which I would like to read into a matrix, which is a vector containing vectors (which contain doubles).

My current codes yields the error "newReader.cpp:22: error: variable ‘std::istringstream reader’ has initializer but incomplete type" Here is the code:

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

using namespace std;

typedef vector<double> Vec; //Vector
typedef vector<Vec> Mat; //Matrix

int main(void){

Mat data;
string line;
    
ifstream myfile ("q.txt");
if( myfile.is_open() ){ while( myfile.good() ){
	while(!std::getline(myfile, line, '\n').eof()) {
   
		istringstream reader(line);
		Vec lineData;
		string::const_iterator i = line.begin();
		while(!reader.eof()) {
			double val;
			reader << val;
			if(reader.fail()) break;
			lineData.push_back(val);
        }
        data.push_back(lineData);
	}
}}
else{ cout<< "Unable to open file." <<endl; }

return 0;
}

Edited 5 Years Ago by MareoRaft: edit code

After adding the sstream header, I have a new error: " newReader.cpp:27: error: no match for ‘operator<<’ in ‘reader << val’ "

(as you can see I have edited the above code to match my current code)

Edited 5 Years Ago by MareoRaft: n/a

That works! Now the only issue is that my program is not recording the last row of the matrix. This seems to be because the program looks for '\n' to indicate where a line ends. The last line does not have '\n' after it.

The simple solution is to add a return to the end of my file, but I am looking for a more robust solution.

Edited 5 Years Ago by MareoRaft: n/a

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

int main()
{
    using namespace std;

    ifstream in("test.txt");

    if (in) {
        typedef double Value;
        typedef vector<Value> Vec;
        typedef vector<Vec> Mat;

        Mat v;

        for (string line; getline(in, line);) {
            istringstream iss(line);

            v.push_back(Vec());
            copy(istream_iterator<Value>(iss), 
                istream_iterator<Value>(), 
                back_inserter(v.back()));
        }

        for (Mat::const_iterator it = v.begin(); it != v.end(); ++it) {
            copy(it->begin(), it->end(), ostream_iterator<Value>(cout, "\t"));
            cout<<'\n';
        }
    }
}

:D

Edited 5 Years Ago by Narue: n/a

Thank you very much for your help. Your code reads the error " error: no matching function for call to ‘std::istream_iterator<double, char, std::char_traits<char>, long int>::istream_iterator(std::istringstream)’ "

I will mark the thread as solved since there is only a small issue standing.

Thank you very much for your help. Your code reads the error " error: no matching function for call to ‘std::istream_iterator<double, char, std::char_traits<char>, long int>::istream_iterator(std::istringstream)’ "

Serves me right for rushing something out without testing it on another compiler. It should work now.

This question has already been answered. Start a new discussion instead.