views:

1480

answers:

2

I am looking for a good example of how to overload the stream input operator (operator>>) to parse some data with simple text formatting. I have read this tutorial but I would like to do something a bit more advanced. In my case I have fixed strings that I would like to check for (and ignore). Supposing the 2D point format from the link were more like

Point{0.3 =>
      0.4 }

where the intended effect is to parse out the numbers 0.3 and 0.4. (Yes, this is an awfully silly syntax, but it incorporates several ideas I need). Mostly I just want to see how to properly check for the presence of fixed strings, ignore whitespace, etc.

Update: Oops, the comment I made below has no formatting (this is my first time using this site). I found that whitespace can be skipped with something like

std::cin >> std::ws;

And for eating up strings I have

static bool match_string(std::istream &is, const char *str){
    size_t nstr = strlen(str);
    while(nstr){
        if(is.peek() == *str){
            is.ignore(1);
            ++str;
            --nstr;
        }else{
            is.setstate(is.rdstate() | std::ios_base::failbit);
            return false;
        }
    }
    return true;
}

Now it would be nice to be able to get the position (line number) of a parsing error.

Update 2: Got line numbers and comment parsing working, using just 1 character look-ahead. The final result can be seen here in AArray.cpp, in the function parse(). The project is a (de)serializable C++ PHP-like array class.

A: 

Take a look at this article - http://www.anthonycramp.name/2008/10/input-stream-your-parse-functions-part.html

adatapost
That article merely indicates how the function prototype should look and discusses pros and cons of using the overloaded operator. Even in part 3 of that series, he only assumes that the implementation of parse() exists. I am looking for a more concrete implementation of that parse() function. The difficulty I have is with how to implement a parser with the basic operations that istream provides.
Victor Liu
@Victor - here is [http://www.csse.monash.edu.au/~damian/papers/PDF/ParserClass.pdf] paper presents an alternative C++-based parser generation scheme.
adatapost
+1  A: 

Your operator>>(istream &, object &) should get data from the input stream, using its formatted and/or unformatted extraction functions, and put it into your object.

If you want to be more safe (after a fashion), construct and test an istream::sentry object before you start. If you encounter a syntax error, you may call setstate( ios_base::failbit ) to prevent any other processing until you call my_stream.clear().

See <istream> (and istream.tcc if you're using SGI STL) for examples.

Potatoswatter