I'm trying to use istringstream
to split a simple string into a series of integers:
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main(){
string s = "1 2 3";
istringstream iss(s);
while (iss)
{
int n;
iss >> n;
cout << "* " << n << endl;
}
}
And i get:
* 1
* 2
* 3
* 3
Why is the last element always coming out twice? How to fix it?
The std::istringstream is a string class object which is used to stream the string into different variables and similarly files can be stream into strings. Objects of this class use a string buffer that contains a sequence of characters. This sequence of characters can be accessed as a string object.
It's coming out twice because your looping is wrong, as explained (indirectly) at http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5 (while (iss)
is not dissimilar from while (iss.eof())
in this scenario).
Specifically, on the third loop iteration, iss >> n
succeeds and gets your 3
, and leaves the stream in a good state. The loop then runs a fourth time due to this good state, and it's not until the next (fourth) iss >> n
subsequently fails that the loop condition is broken. But before that fourth iteration ends, you still output n
... a fourth time.
Try:
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
string s = "1 2 3";
istringstream iss(s);
int n;
while (iss >> n) {
cout << "* " << n << endl;
}
}
Hope this helps:
iss : 1 2 3
Iteration 1
iss : 1 2 3 (Initially)
n=1
iss : 2 3
//* 1 is printed
Iteration 2:
iss : 2 3 (Initially)
n=2
iss : 3
//* 2 is printed
Iteration 3
iss : 3
n=3
iss : ''
Iteration 4
iss : ''
n not changed//Flag set for eof of iss as no further input from stream
iss : ''
And as rightly mentioned by the above post while (iss) is not dissimilar from while (iss.eof()).
Internally, the function(istream::operator>>) accesses the input sequence by first constructing a sentry object (with noskipws set to false[This means that space is separator and your list will be 1,2,3]). Then (if good[here eof not reached]), it calls num_get::get [Get the next integer] to perform both the extraction and the parsing operations, adjusting the stream's internal state flags accordingly. Finally, it destroys the sentry object before returning.
Refer : http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
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