Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does std::find_if used on std::istream_iterators seem to return the last element?

I am learning C++ through Accelerated C++ by Andrew Koenig and Barbara E. Moo. I am trying to understand how input operators work and their relation to STL algorithms.

Here is the piece of code that confuses me:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <cctype>

bool space(char c)
{
    return std::isspace(c);
}

int main()
{
    std::istream_iterator<char> i = std::find_if(
        std::istream_iterator<char>(std::cin),
        std::istream_iterator<char>(),
        space);
    std::cout << *i << std::endl;
    return 0;
}

The code compiles fine but when I run it on any input what it outputs is the last character entered. For example, I expected the output of 123 456 to be but it actually is 6. Similarly, I expected the output of 123456 to be some error because we try to access an element that doesn't exist, yet the output is again . What am I missing?

like image 445
John Avatar asked Dec 12 '25 14:12

John


1 Answers

Why doesn't 123 456 as input produce as output?

From cppreference:

When reading characters, std::istream_iterator skips whitespace by default (unless disabled with std::noskipws or equivalent), while std::istreambuf_iterator does not.

Switching to std::istreambuf_iterator gives the desired behaviour: https://wandbox.org/permlink/RRt8kvyqyvbO1p8m


Why doesn't 123456 as input produce an error?

If there is no space in the input, find_if will return its 2nd argument, which is the end-of-stream iterator.

Dereferencing the end-of-stream iterator is undefined behaviour, which is not guaranteed to produce an error. In fact it doesn't guarantee anything, which means your program might just print the last character in your input.

like image 113
Mark Avatar answered Dec 15 '25 08:12

Mark



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!