I know how to do this in other languages, but not C++, which I am forced to use here.
I have a Set of Strings that I'm printing to out in a list, and they need a comma between each one, but not a trailing comma. In java for instance, I would use a stringbuilder and just delete the comma off the end after I've built my string. How do I do it in C++?
auto iter = keywords.begin();
for (iter; iter != keywords.end( ); iter++ )
{
out << *iter << ", ";
}
out << endl;
I initially tried inserting this block to do it (moving the comma printing here)
if (iter++ != keywords.end())
out << ", ";
iter--;
I hate when the small things trip me up.
EDIT: Thanks everyone. This is why I post stuff like this here. So many good answers, and tackled in different ways. After a semester of Java and assembly (different classes), having to do a C++ project in 4 days threw me for a loop. Not only did I get my answer, I got a chance to think about the different ways to approach a problem like this. Awesome.
I use a little helper class for that:
To use it:
to avoid placing an
if
inside the loop, I use this:It depends on the vector type,
int
, but you can remove it with some helper.There are lots of clever solutions, and too many that mangle the code beyond hope of salvation without letting the compiler do its job.
The obvious solution, is to special-case the first iteration:
It's a dead simple pattern which:
else
block and the loop body can contain arbitrary statements.It may not be the absolutely most efficient code, but the potential performance loss of a single well-predicted branch is very likely to be overshadowed by the massive behemoth that is
std::ostream::operator<<
.You can use a
do
loop, rewrite the loop condition for the first iteration, and use the short-circuit&&
operator and the fact that a valid stream istrue
.One common approach is to print the first item prior to the loop, and loop only over the remaining items, PRE-printing a comma before each remaining item.
Alternately you should be able to create your own stream that maintains a current state of the line (before endl) and puts commas in the appropriate place.
EDIT: You can also use a middle-tested loop as suggested by T.E.D. It would be something like:
I mentioned the "print first item before loop" method first because it keeps the loop body really simple, but any of the approaches work fine.
Assuming a vaguely normal output stream, so that writing an empty string to it does indeed do nothing: