When I try to parse whitespace seperated double values from a string, I found this curious behaviour that the string is read out in a cyclic manner.
Here's the program:
stringstream ss;
string s("1 2 3 4");
double t;
list<double> lis;
for(int j=0; j!=10; ++j){
ss << s;
ss >> t;
lis.push_back(t);
}
for(auto e : lis){
cout << e << " ";
}
Here the output:
1 2 3 41 2 3 41 2 3 41
If I append a trailing space as s= "1 2 3 4 ";
I get
1 2 3 4 1 2 3 4 1 2
Now the questions:
1) If I don't know how many entries are in the string s, how do I read all into the list l?
2) which operator<<
am I actually calling in ss << s;
? Is it specified to read circularly?
3) Can I do the parsing in a better way?
Thanks already!
Here's the fixed code (thanks to timrau):
// declarations as before
ss << s;
while(ss >> t){
lis.push_back(t);
}
// output as before
This produces:
1 2 3 4
as desired. (Don't forget to clear your stringstream
by ss.clear()
before treating the next input. ;))
Another useful comment from HeywoodFloyd: One could also use boost/tokenizer to "split" the string, see this post
To use stringstream class in the C++ program, we have to use the header <sstream>. For Example, the code to extract an integer from the string would be: string mystr(“2019”); int myInt; stringstream (mystr)>>myInt; Here we declare a string object with value “2019” and an int object “myInt”.
A stringstream associates a string object with a stream allowing you to read from the string as if it were a stream (like cin). To use stringstream, we need to include sstream header file. The stringstream class is extremely useful in parsing input.
You cannot std::getline() a std::stringstream ; only a std::string . Read as a string, then use a stringstream to parse it. Hope this helps.
Using the stoi() function The stoi() function converts a string data to an integer type by passing the string as a parameter to return an integer value. The stoi() function contains an str argument. The str string is passed inside the stoi() function to convert string data into an integer value.
You can test the return value of >>
.
while (ss >> t) {
lis.push_back(t);
}
It's not specified to read circularly. It's ss << s
appending "1 2 3 4"
to the end of the stream.
Before the 1st loop:
""
After 1st ss << s
:
"1 2 3 4"
After 1st ss >> t
:
" 2 3 4"
After 2nd ss << s
:
" 2 3 41 2 3 4"
Then it's clear why you get 1 2 3 41 2 3 41 2 3 41
if there is no trailing space in s
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With