Removing a comma from a c++ output

前端 未结 2 970
有刺的猬
有刺的猬 2020-12-07 03:02

I wrote this program that sorts numbers in vectors from greatest to least, it works great but the only thing that is bugging me is trying to remove the comma from the last n

相关标签:
2条回答
  • 2020-12-07 03:57

    If begin, end are at least bidirectional iterators (as yours are), you can just check initially that begin != end; if not print nothing; if so print ", "-puncuated elements incrementing begin != std::prev(end), and finally print *begin(). like so:

    main.cpp

    #include <utility>
    
    template<typename OStream, typename BiIter, typename Punct>
    void punctuated(OStream && out, Punct && punct, BiIter begin, BiIter end)
    {
        if (begin != end) {
            for (--end  ;begin != end; ++begin) {
                std::forward<OStream>(out) << *begin << std::forward<Punct>(punct);
            }
            std::forward<OStream>(out) << *begin;
        }
    }
    
    #include <iostream>
    #include <vector>
    #include <list>
    #include <set>
    
    int main()
    {
        std::vector<int> v0;
        std::vector<int> v1{{1}};
        std::list<int> l{{1,2}};
        std::set<int>s{{3,4,5,6,7}};
        std::cout << "v0 [";
        punctuated(std::cout,",",v0.begin(),v0.end());
        std::cout << "]\n";
        std::cout << "v1 [";
        punctuated(std::cout,",",v1.begin(),v1.end());
        std::cout << "]\n";
        std::cout << "l [";
        punctuated(std::cout,",",l.begin(),l.end());
        std::cout << "]\n";
        std::cout << "s [";
        punctuated(std::cout,"|",s.begin(),s.end());
        std::cout << "]\n";
        return 0;
    }
    

    Output:

    g++ -Wall -Wextra main.cpp && ./a.out
    v0 []
    v1 [1]
    l [1,2]
    s [3|4|5|6|7]
    

    Live

    0 讨论(0)
  • 2020-12-07 04:00

    Rather than removing the simplest way is just to print commas only for other values than the first:

    for (auto i = vi3.begin(); i != vi3.end(); ++i) {
        if(i != vi3.begin()) {
            cout << ", ";
        }
        cout << *i;
    }
    

    I am using this idiom regularly to format e.g. SQL parameter lists, or similar where a delimiter isn't wanted after the last element but for any others.
    There are other ways to detect the first element (e.g. using a bool variable initialized to true before the loop starts, and set to false upon the first iteration).
    For your example it seems just checking for vi3.begin() is the easiest and most natural way.

    Here's the generic variant in pseudo code:

    bool isFirstOutput = true;
    for_each(element in list) {
        if(not isFirstOutput) {
            print delimiter;
        }
        print element;
        isFirstOutput = false;
    }
    
    0 讨论(0)
提交回复
热议问题