Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Join vector of strings to std::ostream (like boost::join)

Tags:

c++

csv

ostream

I have a vector of strings and I want output it to stream (file stream, actually). And I want to have a delimiter between vector elements. There is a way to use standard ostream_iterator

std::vector <std::string> strs;
std::ostream_iterator<std::string> out_file_iterator ( out_file, delim );
std::copy ( strs.begin(), strs.end(), out_file_iterator );

I didn't like this way because there is a delim text after each element, but I don't need to have a delim after last element. I'd like to use something like boost::join. However boost::join returns string and my vector too large to output it to string.

What is most elegant way to achieve my goal?

like image 882
Loom Avatar asked Oct 23 '25 19:10

Loom


1 Answers

For a general solution (untested):

template<class T>
class ostream_join_iterator {
public:

    // Construct like an ostream_iterator.
    ostream_join_iterator(std::ostream& stream,
        const std::string& delimiter = "")
        : stream(stream), delimiter(delimiter), first(true) {}

    // Behave like an output iterator.
    ostream_join_iterator& operator++()    { return *this; }
    ostream_join_iterator& operator++(int) { return *this; }
    ostream_join_iterator& operator*()     { return *this; }

    // Output a delimiter before all but the first element.
    template<class T>
    ostream_join_iterator& operator=(const T& value) {
        if (!first) {
            stream << delimiter;
        } else {
            first = false;
        }
        stream << value;
        return *this;
    }

private:

    std::ostream& stream;
    const std::string delimiter;
    bool first;

};

You can use it like a regular std::ostream_iterator:

std::copy(strings.begin(), strings.end(),
    ostream_join_iterator<std::string>(file, delimiter));
like image 87
Jon Purdy Avatar answered Oct 26 '25 09:10

Jon Purdy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!