Converting a string to a list of key-value pairs I'm trying to convert a string (here after called input) into a vector of key-value pairs, all in C++03 (cannot use C++11, cannot use Boost libs).

The string in question can contain whitespaces. A comma (,) delimits key-value pairs and the equals sign (=) separates the key from the value.
A sample string (also in the code could be: "ab=xy z,time a=1s". Notice the lack of a final ,.

Any improvement is most welcome.

#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;map&gt;


struct Flag_name_value {
    std::string name;
    std::string value;
};

std::istringstream&amp; operator&gt;&gt;(std::istringstream&amp; iss, Flag_name_value&amp; fnv)
{
    char ch; 
    std::ostringstream oss;

    while (iss &gt;&gt; std::noskipws &gt;&gt; ch) {
        std::cout &lt;&lt; ch &lt;&lt; "\n";
        switch(ch) {
            case('='):
                fnv.name = oss.str();
                oss.str("");
                break;
            case(','):
                fnv.value = oss.str();
                oss.str("");
                break;
            default:
                oss &lt;&lt; ch; 
                break;
        }   

        if (!fnv.name.empty() &amp;&amp; !fnv.value.empty())
        {   
            return iss;
        }   
    }   

    // We end here if the string didn't end with ','
    fnv.value = oss.str();
    return iss;
}

int main () {

    std::string input("ab=xy z,time a=1s");

    std::istringstream iss(input);

    std::vector&lt;Flag_name_value&gt; flags;
    while (true) {
        Flag_name_value f;
        iss &gt;&gt; f;
        flags.push_back(f);
        if (!iss) break;
    }

    return 0;

}
First, you can use std::getline to extract key-value pairs from the original string. This can be done by passing , as a delimiter to std::getline:

while (std::getline(iss, token, ',')) { ... }


Notice that you don't have to perform any checks on the stream this way. Once std::getline will reach the end of the stream it will set the eofbit on it, so the loop condition will evaluate to false on next iteration.

Next, use can use std::string::find to find an index of the occurrence of the = character in strings filled by std::getline:

size_t pos = token.find('=');  


After that use can use this index to extract two substrings - your key and your value:  

flag.name    = token.substr(0, pos);
flag.value   = token.substr(pos + 1);


Notice that you can omit the second argument of std::string::substr, since it has the default value of std::string::npos. This value is very huge (in fact, it equals to the maximum value that can be represented by a size type of std::string), but std::string::substr never reads past the end of line, so everything will be good. 

Tie all this together and you'll get a small and readable solution:

std::string input("ab=xy z,time a=1s");
std::istringstream iss(input);

std::vector&lt;Flag_name_value&gt; flags;

std::string token;
Flag_name_value flag;
while (std::getline(iss, token, ',')) {
    size_t pos   = token.find('=');
    flag.name    = token.substr(0, pos);
    flag.value   = token.substr(pos + 1);
    flags.push_back(flag);
}