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 co
Because everyone has decided to do this with while loops, I'll give an example with for loops.
for (iter = keywords.begin(); iter != keywords.end(); iter++) {
if (iter != keywords.begin()) cout << ", ";
cout << *iter;
}
Something like this?
while (iter != keywords.end())
{
out << *iter;
iter++;
if (iter != keywords.end()) cout << ", ";
}
In python we just write:
print ", ".join(keywords)
so why not:
template<class S, class V>
std::string
join(const S& sep, const V& v)
{
std::ostringstream oss;
if (!v.empty()) {
typename V::const_iterator it = v.begin();
oss << *it++;
for (typename V::const_iterator e = v.end(); it != e; ++it)
oss << sep << *it;
}
return oss.str();
}
and then just use it like:
cout << join(", ", keywords) << endl;
Unlike in the python example above where the " "
is a string and the keywords
has to be an iterable of strings, here in this C++ example the separator and keywords
can be anything streamable, e.g.
cout << join('\n', keywords) << endl;
Using boost:
std::string add_str("");
const std::string sep(",");
for_each(v.begin(), v.end(), add_str += boost::lambda::ret<std::string>(boost::lambda::_1 + sep));
and you obtain a string containing the vector, comma delimited.
EDIT: to remove the last comma, just issue:
add_str = add_str.substr(0, add_str.size()-1);
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:
if(!keywords.empty())
{
auto iter = keywords.begin();
while(true)
{
out << *iter;
++iter;
if(iter == keywords.end())
{
break;
}
else
{
out << ", ";
}
}
}
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.
to avoid placing an if
inside the loop, I use this:
vector<int> keywords = {1, 2, 3, 4, 5};
if (!keywords.empty())
{
copy(keywords.begin(), std::prev(keywords.end()),
std::ostream_iterator<int> (std::cout,", "));
std::cout << keywords.back();
}
It depends on the vector type, int
, but you can remove it with some helper.