Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Example of overloading C++ extraction operator >> to parse data

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.

like image 666
Victor Liu Avatar asked Nov 14 '22 14:11

Victor Liu


1 Answers

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.

like image 116
Potatoswatter Avatar answered Dec 19 '22 08:12

Potatoswatter