I was using the std::stream_iterator, for example:
std::vector vals; vals.push_back (12); vals.push_back (22); vals.push_back (5); vals.push_back (30); // The std::ostream_iterator appends the "," std::ostringstream str3; std::copy (vals.begin(), vals.end(), std::ostream_iterator (str3, ",")); CPPUNIT_ASSERT_EQUAL (std::string ("12,22,5,30,"), str3.str());
It has the “,” after the last item.
So here’s an implementation that doesn’t append the seperator after the last one:
#ifndef INCLUDED_OUTITER_H #define INCLUDED_OUTITER_H #include /** * A replacement for std::ostream_iterator that doesn't put the * seperator after the last item. */ template<typename Type, typename CharType = char, typename Traits = std::char_traits > class outiter : public std::iterator { public: typedef CharType char_type; typedef Traits traits_type; typedef std::basic_ostream ostream_type; /// Initialize from a stream outiter (ostream_type &stream) : m_stream (&stream), m_string (0), m_started (false) {} /// Copy constructor outiter (const outiter ©) : m_stream (copy.m_stream), m_string (copy.m_string), m_started (copy.m_started) {} /// Initialize from a stream and the seperator outiter (ostream_type &stream, const CharType *str) : m_stream (&stream), m_string (str), m_started (false) {} /// Assignment actually does the output outiter & operator=(const Type &value) { if (!m_started) { m_started = true; } else if (m_string) { (*m_stream) << m_string; } (*m_stream) << value; return *this; } /// Just return a reference to this outiter & operator*() { return *this; } /// Just return a reference to this outiter & operator++() { return *this; } /// Just return a reference to this outiter & operator++(int) { return *this; } private: /// The stream to write to ostream_type * m_stream; /// The seperator (may be NULL) const char_type * m_string; /// Flag to indicate if we've output anything bool m_started; }; #endif /* INCLUDED_OUTITER_H */
And here’s the corresponding code to use it:
std::ostringstream str; std::copy (vals.begin(), vals.end(), outiter (str, ",")); CPPUNIT_ASSERT_EQUAL (std::string ("12,22,5,30"), str.str());