Chen
Chen

Reputation: 330

std::istreambuf_iterator equality when using seekg

I am puzzled by the output of the code below:

std::string content = "abcdefghijklmnopqrstuvwxyz1234567890";

std::istringstream iss(content);
iss.seekg(10);
std::istreambuf_iterator<char> it{iss}, end;
EXPECT_TRUE(iss.good());

iss.seekg(35);
std::istreambuf_iterator<char> it2{iss};
EXPECT_TRUE(iss.good());

iss.seekg(0);
std::istreambuf_iterator<char> it3{iss};
EXPECT_TRUE(iss.good());

bool oneAndTwo = it == it2;
bool twoAndThree = it2 == it3;
std::cout << std::boolalpha;
std::cout << oneAndTwo << "\n";    // true
std::cout << twoAndThree << "\n";  // true

std::cout << "char at the iterators: ";
std::cout << std::string(1, *it) << " "   // a
    << std::string(1, *it2) << " "        // a
    << std::string(1, *it3) << "\n"; // a

EXPECT_TRUE(iss.good());
std::string s1{it, end};  // abcdefghijklmnopqrstuvwxyz1234567890
std::cout << s1 << "\n";

std::string s2{it2, end};  // a
std::cout << s2 << "\n";

std::string s3{it3, end}; // a
std::cout << s3 << "\n";

And the output from std::cout:

true
true
char at the iterators: a a a
abcdefghijklmnopqrstuvwxyz1234567890
a
a

Two questions based on the output:

  1. seekg made a difference on the constructed std::istreambuf_iterator right after. But why are all the iterators equal if I compare one iterator with another (it, it2, and it3 are equal)?

  2. If they are really equal, why are the constructed strings from them different? And why does it give me the full string, whereas the other two iterators only give the 1st character "a"?

Is the stream corrupted? Where did I mess it up?

Upvotes: 2

Views: 52

Answers (1)

nilo
nilo

Reputation: 1130

seekg made a difference on the constructed std::istreambuf_iterator right after. But why are all the iterators equal if I compare one iterator with another (it, it2, and it3 are equal)?

Because std::istreambuf_iterator is a single-pass input iterator that reads successive characters from the std::basic_streambuf object for which it was constructed (see cppreference).

So moving in the stream impacts all the iterators.

If they are really equal, why are the constructed strings from them different? And why does it give me the full string, whereas the other two iterators only give the 1st character "a"?

Because when you construct the first string, you consume the stream. There is no difference between the three iterators. If you try to construct one additional string from the first iterator at the end, you will get 'a' too. I'm not entirely sure why 'a', but since the stream is already consumed, I'm guessing it's undefined behavior.

Upvotes: 2

Related Questions