0

This is basically what I want to do.

int main(int argc, char* argv[])
{
    std::stringstream ss;
    ss << "12345";
    ss.seekp(-1, std::ios::end);
    ss << '\0';
    assert(ss.str() == "1234");     // nope!
    return 0;
}

This question seems like a duplicate, but the answer is about writing a sequence of tokens and not actually addresses the original question.

MarkB
  • 672
  • 2
  • 9
  • 1
    I'm curious what the use case for this is, like, in what context do you need to perform this operation? – Borgleader Jan 06 '23 at 23:04
  • @Borgleader, I don't *need* to perform this operation. I have other options available for either 1) not generating the final character or 2) erasing the final character from the resulting string. I am just asking whether it is possible to throwaway the last character using std::stringstream members. – MarkB Jan 06 '23 at 23:17
  • 1
    `ss.str(ss.str().substr(0, ss.str().size() - 1));` seems like a nice awful way to do it. https://godbolt.org/z/4KcqzYqGT – Retired Ninja Jan 06 '23 at 23:28
  • @RetiredNinja. that is less efficient than `auto str = ss.str(); str.pop_back();` since `substr` creates a 2nd string. – MarkB Jan 06 '23 at 23:31
  • 8
    It is a pain in the neck to remove stuff you don't want from a stream. Do everything in your power to not put it there in the first place. – user4581301 Jan 06 '23 at 23:31
  • 1
    Side note: `std::string` and `std::stringstream` are both happy holding an embedded null: https://godbolt.org/z/fdc5xzW5a You may or may not, depending on the terminal, see signs of the null, but it's there. The size of the string is still 5 – user4581301 Jan 06 '23 at 23:40
  • @MarkB That was a thought, but doesn't provide the desired result unless you also assign the string back. `ss.str(str);` Besides, I was going for maximum ugly in a one liner. https://godbolt.org/z/4MGeMhnf1 – Retired Ninja Jan 06 '23 at 23:41

1 Answers1

2

The best I can think of is

std::string contents = std::move(ss).str();
contents.resize(contents.size() - 1); // assumes size() > 0 !!
ss.str(std::move(contents));

Note that this is distinct from the solution in the comments: judicious choice of functions and overloads should avoid reallocating the buffer and copying the contents. (ss.str() would be a copy, contents.substr(...) would be a copy, and ss.str(contents) would be a copy.) Note that this requires C++20, and e.g. Clang's libc++ doesn't seem updated yet.

HTNW
  • 27,182
  • 1
  • 32
  • 60
  • This is exactly what I had in mind too but I thought that one could do something nifty with the `rdbuf()` and then I got distracted :-) +1 – Ted Lyngmo Jan 07 '23 at 01:09