Printing lists with commas C++

2018-12-31 07:54发布

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.

24条回答
不流泪的眼
2楼-- · 2018-12-31 08:37

This one overloads the stream operator. Yes global variables are evil.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>

int index = 0;
template<typename T, template <typename, typename> class Cont>
std::ostream& operator<<(std::ostream& os, const Cont<T, std::allocator<T>>& vec)
{
    if (index < vec.size()) {
        if (index + 1 < vec.size())
            return os << vec[index++] << "-" << vec;
        else
            return os << vec[index++] << vec;
    } else return os;
}

int main()
{
    std::vector<int> nums(10);
    int n{0};
    std::generate(nums.begin(), nums.end(), [&]{ return n++; });
    std::cout << nums << std::endl;
}
查看更多
君临天下
3楼-- · 2018-12-31 08:38

There is a little problem with the ++ operator you are using.

You can try:

if (++iter != keywords.end())
    out << ", ";
iter--;

This way, ++ will be evaluated before compare the iterator with keywords.end().

查看更多
余欢
4楼-- · 2018-12-31 08:38

Following should do:-

 const std::vector<__int64>& a_setRequestId
 std::stringstream strStream;
 std::copy(a_setRequestId.begin(), a_setRequestId.end() -1, std::ostream_iterator<__int64>(strStream, ", "));
 strStream << a_setRequestId.back();
查看更多
君临天下
5楼-- · 2018-12-31 08:40

Can use functors:

#include <functional>

string getSeparatedValues(function<bool()> condition, function<string()> output, string separator)
{
    string out;
    out += output();
    while (condition())
        out += separator + output();
    return out;
}

Example:

if (!keywords.empty())
{
    auto iter = keywords.begin();
    cout << getSeparatedValues([&]() { return ++iter != keywords.end(); }, [&]() { return *iter; }, ", ") << endl;
}
查看更多
浪荡孟婆
6楼-- · 2018-12-31 08:41

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;
}
查看更多
梦该遗忘
7楼-- · 2018-12-31 08:43

I think this should work

while (iter != keywords.end( ))
{

    out << *iter;
    iter++ ;
    if (iter != keywords.end( )) out << ", ";
}
查看更多
登录 后发表回答