简体   繁体   中英

Can we change the default behavior of “>>” overloaded operator for stringstream object?

My requirement described as below. I am reading a file in stringstream object which contain

"NECK_AP \
UL, 217.061, -40.782\n\
UR, 295.625, -40.782\n\
LL, 217.061, 39.194\n\
LR, 295.625, 39.194".

when I am trying to populate the value in variables I am getting "," also along with it. Can any one suggest so that I can store all these value in respective variable without ","

Just a sample code to help the situation:

int _tmain(int argc, _TCHAR* argv[])
{
    char pause;
    stringstream stream;
    stream.str("NECK_AP \
UL, 217.061, -40.782\n\
UR, 295.625, -40.782\n\
LL, 217.061, 39.194\n\
LR, 295.625, 39.194");

    string value1,value2,value3,value4;

    stream >> value1>>value2>>value3>>value4;
    cout << value1<<value2<<value3<<value4<<endl;           

    cin >> pause;
    return 0;
}

Output

NECT_AP UL,217.061,-40.782

Required Output

NECT_AP UL 217.061 -40.782

You need to understand that functions(or operators, etc.) are (most of the time) written to do some certain job. Operator >> has a job of getting data from stream to some place. That's its job and it should be this. What you want to do, is write new function(or use existing one) that will later change the value, the way you want it.

What you want to do can be easily achieved with help of standard library:

#include <algorithm>
//some code...
std::replace_if(value1.begin(), value1.end(), [](char x){return x == ',';}, ' ');

And do it for each value. Alternatively, load everything into one string, use this function on this string, and print its contents. What does it do? replace_if takes four arguments: container's beginning and end iterator(first two arguments), some predicate function(I'm using so called lambda expression, or anonymous function; but you can write separate function and provide its name, no problem!), and new value. Basically it can be translated to "replace every character in string with ' ', if it meets predicate(in other words, is colon).

You can do this. operator>> for an std::string skips white-space characters, then reads characters into the supplied variable until it gets to another white-space character.

The stream has an associated locale that's used to determine what characters are or aren't considered "white-space". We can write our own locale that classifies , as 'white-space`, tell the stream to use that locale, and read our data as desired.

For the sake of simplicity, I've written some code to just read all the strings into a vector, then display each string it read on its own line, so it's easy to see exactly what it read into each string.

#include <locale>
#include <string>
#include <vector>
#include <sstream>
#include <iterator>
#include <algorithm>
#include <iostream>

struct reader: std::ctype<char> {
    reader(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table() {
        static std::vector<std::ctype_base::mask> 
            rc(std::ctype<char>::table_size,std::ctype_base::mask());

        rc[','] = std::ctype_base::space;
        rc['\n'] = std::ctype_base::space;
        rc[' '] = std::ctype_base::space;
        return &rc[0];
    }
};

int main() {
    std::istringstream infile("NECK_AP \
                              UL, 217.061, -40.782\n\
                              UR, 295.625, -40.782\n\
                              LL, 217.061, 39.194\n\
                              LR, 295.625, 39.194");

    infile.imbue(std::locale(std::locale(), new reader));

    std::vector<std::string> d { std::istream_iterator<std::string>(infile),
        std::istream_iterator<std::string>() };

    std::copy(d.begin(), d.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM