This splits to smaller stages:
- How do I calculate the total length of the all the strings in the vector?
- Allocate the char* mem space
- 开发者_运维技巧Copy the vector strings into that space
Is there a quick elegant way to do that?
The most elegant, but perhaps not the quickest, way that I can think of would be the following:
std::string s = std::accumulate(v.begin(), v.end(), std::string());
char * c = new char[s.size() + 1];
std::strcpy(c,s.c_str());
Although I'm not myself a fan of naked dynamic allocation, and personally would never use it, I'll leave that for you to sort out.
If you need to add a space delimiter between the elements, it becomes a bit more complex, and I would probably use a different solution, like this:
std::ostringstream oss;
std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(oss," "));
size_t sz = oss.str().size();
if(sz) --sz; // truncate trailing space if there is one
char * c = new char[sz+1];
std::copy_n(oss.str().c_str(), sz, c);
c[sz] = 0;
Here's a C++0x implementation:
#include <cstddef>
#include <algorithm>
#include <numeric>
#include <string>
#include <vector>
std::vector<char> concat_strings(std::vector<std::string> const& vecs)
{
std::size_t const cumulative_length = std::accumulate(
vecs.begin(),
vecs.end(),
static_cast<std::size_t>(0),
[](std::size_t const acc, std::string const& str)
{
return acc + str.size();
}
);
std::vector<char> ret;
ret.reserve(cumulative_length);
std::for_each(
vecs.begin(),
vecs.end(),
[&ret](std::string const& str)
{
ret.insert(ret.end(), str.begin(), str.end());
}
);
return ret;
}
The resulting std::vector<char>
is your effective char*
.
For C++03 it will be much the same, but you'll need proper functors in place of the lambdas (or use a C++03 lambda library e.g. Boost.Phoenix).
It's not an elegant requirement, so there's no elegant solution I can think of.
Untested code
vector<string> vec = ...;
size_t total_size = 0;
for (size_t i = 0; i < vec.size(); ++i)
total_size += vec[i].size();
char* mem = new char[total_size];
char* p = mem;
for (size_t i = 0; i < vec.size(); ++i)
{
memcpy(p, vec[i].data(), vec[i].size());
p += vec[i].size();
}
Here is STL way:
#include <algorithm> // std::copy
#include <iostream> // std::cout
#include <iterator> // std::ostream_iterator
#include <sstream> // std::ostring_stream
#include <string> // std::string
#include <vector> // std::Vector
using namespace std;
typedef std::vector<std::string> string_vector;
int main( int argc, char ** argv )
{
string_vector v;
v.push_back("string 1, ");
v.push_back("string 2, ");
v.push_back("string 3");
std::ostringstream os;
std::copy( v.begin(), v.end(), std::ostream_iterator<std::string>( os, "" ) );
std::string result = os.str();
std::cout << "result: " << result << std::endl;
return 0;
}
Output:
result: string 1, string 2, string 3
精彩评论