tags:

views:

100

answers:

5

I have a std::istream which refers to matrix data, something like:

0.0 1.0 2.0
3.0 4.0 5.0

Now, in order to assess the number of columns I would like to have some code like:

std::vector<double> vec;
double x;
while( (...something...) && (istream >> x) )
{
    vec.push_back(x); 
}
//Here vec should contain 0.0, 1.0 and 2.0

where the ...something... part evaluates to false after I read 2.0 and istream at the point should be at 3.0 so that the next

istream >> x;

should set x equal to 3.0.

How would you achieve this result? I guess that the while condition

Thank you very much in advance for your help!

+3  A: 

Read the lines into a std::string using std::string::getline(), then assign the string to a std::istringstream object, and extract the data from that rather than directly from istream.

Clifford
Sorry I did not make this clear but this is what I am trying to avoid. Point is I do not know in advance if the matrix is going to have many cols or many rows and having string store 10.000 doubles is not a very efficient approch to the problem :) Sorry again for not making this clear, my fault.
KRao
A: 

Read the number, then read one character to see if it's newline.

Messa
+1  A: 

You can use std::istream::peek() to check if the next character is a newline. See this entry in the cplusplus.com reference.

MKroehnert
+3  A: 

Use the peek method to check the next character:

while ((istream.peek()!='\n') && (istream>>x))
tzaman
This is easily broken if the line contains *any* white-space before the <newline>
Clifford
True; there's no error-checking at all here, I'm just assuming the input is well-formed.
tzaman
+1  A: 
std::vector<double> vec;
{
   std::string line;
   std::getline( ifile, line );
   std::istringstream is(line);
   std::copy( std::istream_iterator<double>(is), std::istream_iterator<double>(),
              std::back_inserter(vec) );
}
std::cout << "Input has " << vec.size() << " columns." << std::endl;
std::cout << "Read values are: ";
std::copy( vec.begin(), vec.end(), 
           std::ostream_iterator<double>( std::cout, " " ) );
std::cout << std::endl;
David Rodríguez - dribeas
OP specifically mentioned not wanting to buffer a whole line first.
tzaman
His proposed code requests that after the while the vector should contain the first line: `//Here vec should contain 0.0, 1.0 and 2.0`. Does he not want to read a line or the whole file?
David Rodríguez - dribeas
Yes I want to end the while loop after the first line has been read (and keep the rest in istream for further reading) but I would like to avoid having to create a string to store the first whole line before putting it in the vector.
KRao