¿Cómo puedo imprimir una lista de elementos separados por comas?
Sé cómo hacer esto en otros lenguajes, pero no en C++, que me veo obligado a usar aquí.
Tengo un conjunto de cadenas ( keywords
) en las que estoy imprimiendo out
como una lista, y las cadenas necesitan una coma entre ellas, pero no una coma al final. En Java, por ejemplo, usaría a StringBuilder
y simplemente eliminaría la coma al final después de haber creado mi cadena. ¿Cómo puedo hacerlo en C++?
auto iter = keywords.begin();
for (iter; iter != keywords.end( ); iter++ )
{
out << *iter << ", ";
}
out << endl;
Inicialmente intenté insertar el siguiente bloque para hacerlo (moviendo la impresión de coma aquí):
if (iter++ != keywords.end())
out << ", ";
iter--;
Aceptado
Utilice un infix_iterator:
// infix_iterator.h
//
// Lifted from Jerry Coffin's 's prefix_ostream_iterator
#if !defined(INFIX_ITERATOR_H_)
#define INFIX_ITERATOR_H_
#include <ostream>
#include <iterator>
template <class T,
class charT=char,
class traits=std::char_traits<charT> >
class infix_ostream_iterator :
public std::iterator<std::output_iterator_tag,void,void,void,void>
{
std::basic_ostream<charT,traits> *os;
charT const* delimiter;
bool first_elem;
public:
typedef charT char_type;
typedef traits traits_type;
typedef std::basic_ostream<charT,traits> ostream_type;
infix_ostream_iterator(ostream_type& s)
: os(&s),delimiter(0), first_elem(true)
{}
infix_ostream_iterator(ostream_type& s, charT const *d)
: os(&s),delimiter(d), first_elem(true)
{}
infix_ostream_iterator<T,charT,traits>& operator=(T const &item)
{
// Here's the only real change from ostream_iterator:
// Normally, the '*os << item;' would come before the 'if'.
if (!first_elem && delimiter != 0)
*os << delimiter;
*os << item;
first_elem = false;
return *this;
}
infix_ostream_iterator<T,charT,traits> &operator*() {
return *this;
}
infix_ostream_iterator<T,charT,traits> &operator++() {
return *this;
}
infix_ostream_iterator<T,charT,traits> &operator++(int) {
return *this;
}
};
#endif
El uso sería algo como:
#include "infix_iterator.h"
// ...
std::copy(keywords.begin(), keywords.end(), infix_iterator(out, ","));
En un compilador experimental listo para C++ 17 que estará disponible próximamente, puede usar std::experimental::ostream_joiner
:
#include <algorithm>
#include <experimental/iterator>
#include <iostream>
#include <iterator>
int main()
{
int i[] = {1, 2, 3, 4, 5};
std::copy(std::begin(i),
std::end(i),
std::experimental::make_ostream_joiner(std::cout, ", "));
}
Ejemplos en vivo usando GCC 6.0 SVN y Clang 3.9 SVN