tags:

views:

353

answers:

4

I need to use C++ to read in text with spaces, followed by a numeric value.

For example, data that looks like:

text1
1.0
text two 
2.1
text2 again
3.1

can't be read in with 2 "infile >>" statements. I'm not having any luck with getline either. I ultimately want to populate a struct with these 2 data elements. Any ideas?

A: 

If you can be sure that your input is well-formed, you can try something like this sample:

#include <iostream>
#include <sstream>

int main()
{
    std::istringstream iss("text1 1.0 text two 2.1 text2 again 3.1");

    for ( ;; )
    {
     double x;
     if ( iss >> x )
     {
      std::cout << x << std::endl;
     }
     else
     {
      iss.clear();
      std::string junk;
      if ( !(iss >> junk) )
       break;
     }
    }
}

If you do have to validate input (instead of just trying to parse anything looking like a double from it), you'll have to write some kind of parser, which is not hard but boring.

atzz
Maybe I don't remember the semantics of std::string's operator>> correctly, but doesn't that fail to collect any whitespace in the text field?
Andrew Beyer
Yes, the stream's operator>>'s all skip over whitespace ( http://physical-thought.blogspot.com/2008/06/c-dealing-with-excess-whitespace.html ).
Max Lybbert
Yes it will skip the whitespace, but the author was interested in numbers only. What I wrote here is just a "quick and dirty" way of parsing out all whitespace-separated numbers from a stream.
atzz
+1  A: 

Why? You can use getline providing a space as line separator. Then stitch extracted parts if next is a number.

Marcin Gil
+1  A: 

The standard IO library isn't going to do this for you alone, you need some sort of simple parsing of the data to determine where the text ends and the numeric value begins. If you can make some simplifying assumptions (like saying there is exactly one text/number pair per line, and minimal error recovery) it wouldn't be too bad to getline() the whole thing into a string and then scan it by hand. Otherwise, you're probably better off using a regular expression or parsing library to handle this, rather than reinventing the wheel.

Andrew Beyer
A: 

Pseudocode.

This should work. It assumes you have text/numbers in pairs, however. You'll have to do some jimmying to get all the typing happy, also.

while( ! eof)
   getline(textbuffer)
   getline(numberbuffer)
   stringlist = tokenize(textbuffer)
   number = atof(numberbuffer)
Paul Nathan