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;
}

istringstream is declared in the <sstream> header.

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)

operator<< is for output streams, operator>> is for input streams.

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.

#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

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.

Works beautifully! Many thanks!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.