Reputation: 33
I need to read some input that is delimited by a whitespace, the main construction I used for this is:
while(std::getline(std::cin, s, ' ')){
std::cout << s << std::endl;
}
For the input: "this is some text"
The output for S will be: "this", "is", "some", thus skipping the last piece of input after the last whitespace.
I want to include the last piece of input in my program as well, so I went looking for a solution and found the following:
while (std::getline(std::cin, line)) {
std::istringstream iss(line);
while (std::getline(iss, s, ' ')) {
std::cout << s << std::endl;
}
}
For the input: "this is some text"
The output for S will be: "this", "is", "some", "text", which is exactly what I want.
My question is: why does reading from std::cin with a delimiter skip the input after the last occurrence of the delimiter, but reading from std::istringstream does not?
Upvotes: 3
Views: 797
Reputation: 16945
My question is: why does reading from
std::cin
with a delimiter skip the input after the last occurrence of the delimiter, but reading fromstd::istringstream
does not?
It doesn't.
In your first example:
while(std::getline(std::cin, s, ' ')){
std::cout << s << std::endl;
}
You are specifically reading items from newline that are literally delimited by a single space. Because the line is (ostensibly) ended with a newline, it will never finish extracting from the input string as it is expecting either ' '
or an EOF.
In your second example:
while (std::getline(std::cin, line)) {
std::istringstream iss(line);
while (std::getline(iss, s, ' ')) {
std::cout << s << std::endl;
}
}
The std::getline
in the first while will strip the newline from your example sentence. Then items are extracted according to some basic rules.
Here are the rules (from cppreference):
Extracts characters from input and appends them to str until one of the following occurs (checked in the order listed)
a) end-of-file condition on input, in which case, getline sets eofbit.
b) the next available input character is delim, as tested by Traits::eq(c, delim), in which case the delimiter character is extracted from input, but is not appended to str.
c) str.max_size() characters have been stored, in which case getline sets failbit and returns.
Upvotes: 4