I would like to copy the contents of a vector
to one long string
with a custom delimiter. So far, I\'ve tried:
// .h
string getLabe
Use delimiter.c_str() as the delimiter:
copy(x.begin(),x.end(), ostream_iterator<int>(s,delimiter.c_str()));
That way, you get a const char*
pointing to the string, which is what ostream_operator
expects from your std::string
.
int array[ 6 ] = { 1, 2, 3, 4, 5, 6 };
std::vector< int > a( array, array + 6 );
stringstream dataString;
ostream_iterator<int> output_iterator(dataString, ";"); // here ";" is delimiter
std::copy(a.begin(), a.end(), output_iterator);
cout<<dataString.str()<<endl;
output= 1;2;3;4;5;6;
C++11:
vector<string> x = {"1", "2", "3"};
string s = std::accumulate(std::begin(x), std::end(x), string(),
[](string &ss, string &s)
{
return ss.empty() ? s : ss + "," + s;
});
Another way to do it:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
template <typename T>
string join(const T& v, const string& delim) {
ostringstream s;
for (const auto& i : v) {
if (&i != &v[0]) {
s << delim;
}
s << i;
}
return s.str();
}
int main() {
cout << join(vector<int>({1, 2, 3, 4, 5}), ",") << endl;
}
(c++11 range-based for loop and 'auto' though)
I know this is an old question, but I have a similar problem and none of the above answers suits all my needs, so I'll post here my solution.
My requirements are:
operator<<()
int8_t
and uint8_t
are handled as char
s by std::stringstream
: maybe this is what you want or maybe not, so I want to be able to make this choice)char
s and std::string
sThis assumes C++11.
I choose to use std::stringstream
because it implements a standard but still customizable way to convert something to a string.
Any comments are very welcome.
#include <iterator>
#include <sstream>
#include <string>
#include <iostream> // used only in main
#include <vector> // used only in main
template< typename T >
typename std::iterator_traits< T >::value_type
identity(typename std::iterator_traits< T >::value_type v) {
return v;
}
template< typename T > using IdentityType = decltype(identity< T >);
template< class InItr,
typename StrType1 = const char *,
typename StrType2 = const char *,
typename StrType3 = const char *,
typename Transform = IdentityType< InItr > >
std::string join(InItr first,
InItr last,
StrType1 &&sep = ",",
StrType2 &&open = "[",
StrType3 &&close = "]",
Transform tr = identity< InItr >) {
std::stringstream ss;
ss << std::forward< StrType2 >(open);
if (first != last) {
ss << tr(*first);
++first;
}
for (; first != last; ++first)
ss << std::forward< StrType1 >(sep) << tr(*first);
ss << std::forward< StrType3 >(close);
return ss.str();
}
int main(int argc, char** argv) {
const std::vector< int > vec{2, 4, 6, 8, 10};
std::cout << join(vec.begin(), vec.end()) << std::endl;
std::cout << join(vec.begin(), vec.end(), "|", "(", ")",
[](int v){ return v + v; }) << std::endl;
const std::vector< char > vec2{2, 4, 6, 8, 10};
std::cout << join(vec2.begin(), vec2.end()) << std::endl;
std::cout << join(vec2.begin(), vec2.end(), "|", "(", ")",
[](char v){ return static_cast<int>(v); }) << std::endl;
}
outputs something like:
[2,4,6,8,10]
(4|8|12|16|20)
[<unprintable-char>,<unprintable-char>,<unprintable-char>,
]
(2|4|6|8|10)
std::string Gesture::getLabeledPointsString(const std::string delimiter) {
return boost::join(getLabeledPoints(), delimiter);
}
I am not that convinced about introducting getLabeledPointsString
at this point ;)