C++ cout auto separator

后端 未结 7 1746
半阙折子戏
半阙折子戏 2020-12-13 17:36

I am wondering if there is way that std::cout automatically will insert some predefined value between printed sequences.

For example:

st         


        
相关标签:
7条回答
  • 2020-12-13 17:50

    If you're just looking for a way to print a vector with its elements properly delimited (and without an extra delimiter at the end), try this:

    #include <iostream>
    #include <vector>
    
    int main()
    {
      std::vector<int> v{1, 2, 3};
    
      auto it = v.begin();
      if (it != v.end())
      {
        std::cout << *it;
        ++it;
      }
    
      for (; it != v.end(); ++it)
      {
        std::cout << ", " << *it;
      }
    }
    
    0 讨论(0)
  • 2020-12-13 17:51

    How about using the ostream_iterator

    int main()
    {
         std::vector<int> data {2,3,33,45};
         std::copy(std::begin(data), std::end(data),
                   std::ostream_iterator(std::cout, " "));
         std::cout << "\n";
    }
    
    0 讨论(0)
  • 2020-12-13 17:53

    A C++17 fold expression with the comma operator can create a nice one-liner:

    [](auto &&...xs){ ((std::cout << xs << ',') , ...); }(2,3,33,45);
    
    0 讨论(0)
  • 2020-12-13 17:56

    Well, I got beaten to it. I'll post this anyway.

    Edit : well, after reading Nim's answer, mine does achieve the exact syntax OP wished for.

    #include <iostream>
    #include <algorithm>
    
    struct with_separator {
        with_separator(std::string sep)
        : sep(std::move(sep)) {}
    
        std::string sep;
    };
    
    struct separated_stream {
        separated_stream(std::ostream &stream, std::string sep)
        : _stream(stream), _sep(std::move(sep)), _first(true) {}
    
        template <class Rhs>
        separated_stream &operator << (Rhs &&rhs) {
            if(_first)
                _first = false;
            else
                _stream << _sep;
    
            _stream << std::forward<Rhs>(rhs);
            return *this;
        }
    
        separated_stream &operator << (std::ostream &(*manip)(std::ostream&)) {
            manip(_stream);
            return *this;
        }
    
        private:
        std::ostream &_stream;
        std::string _sep;
        bool _first;
    };
    
    separated_stream operator << (std::ostream &stream, with_separator wsep) {
        return separated_stream(stream, std::move(wsep.sep));
    }
    
    int main()
    {
        std::cout << with_separator(", ") << 1 << 2 << 3 << std::endl;
    }
    

    Output :

    1, 2, 3
    
    0 讨论(0)
  • 2020-12-13 18:06

    Simple answer is No, however, you can roll your own...

    #include <iostream>
    #include <sstream>
    
    using namespace std;
    
    struct set_some_separator{
        set_some_separator(const char* sep) : _sep(sep)
        { };
    
        template <typename T>
        set_some_separator& operator<<(const T& v)
        {
            _str << v << _sep;
            return *this;
        }
    
        friend
        ostream& operator<<(ostream& os, const set_some_separator& s)
        { return os << s._str.str(); }
    
        const char* _sep;
        ostringstream _str;
    };
    
    int main()
    {
        cout << (set_some_separator(" ") << 2 << 3 << 33 << 45) << endl;
    }
    

    Okay the format of the cout is slightly different, hey-ho...

    0 讨论(0)
  • 2020-12-13 18:08

    Not quite the same thing, but:

    #include <array>
    #include <iostream>
    #include <iterator>
    
    int main() {
        std::array<int, 3> data = { 1, 2, 3 };
        std::ostream_iterator<int> out(std::cout, " ");
        std::copy(data.begin(), data.end(), out);
        std::cout << '\n';
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题