c++ - std::istreambuf_iterator equality when using seekg - Stack Overflow

admin2025-05-01  3

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?

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?

Share Improve this question edited Jan 4 at 3:37 Chen asked Jan 3 at 20:47 ChenChen 3303 silver badges13 bronze badges 1
  • Side note: nothing in this code needs the extra stuff that std::endl does. Use '\n' to end a line unless you have a good reason not to. – Pete Becker Commented Jan 3 at 22:01
Add a comment  | 

1 Answer 1

Reset to default 2

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.

转载请注明原文地址:http://anycun.com/QandA/1746060928a91571.html