我有一个完全用字符串启动的std::vector<const char*> v
向量。如何将其复制到已初始化的void*
?
int main() {
std::vector<const char*> v;
v.push_back("abc");
v.push_back("def");
void* b = malloc(6);
// how to copy v in to b?
}
谢谢
答案 0 :(得分:3)
您可以使用基于范围的语句。例如
void *p = b;
for ( const char *s : v )
{
size_t n = std::strlen( s );
std::memcpy( p, s, n );
p = ( char * )p + n;
}
使用标头std::accumulate
<numeric>
也可以这样做
例如
#include <iostream>
#include <vector>
#include <numeric>
#include <cstring>
int main()
{
std::vector<const char*> v;
v.push_back( "abc" );
v.push_back( "def" );
void *b = new char[6];
auto p = std::accumulate( v.begin(), v.end(), b,
[]( void *acc, const char *s ) -> void *
{
size_t n = std::strlen( s );
return ( ( char * )std::memcpy( acc, s, n ) + n );
} );
std::cout.write( (const char * )b , ( const char * )p - ( const char * )b );
std::cout << std::endl;
return 0;
}
输出
abcdef
考虑到编写
会更好void* b = new char[6];
答案 1 :(得分:0)
遍历向量,每次都按指针移动指针。
答案 2 :(得分:0)
int currentIndex = 0;
for(int i = 0; i < v.length(); i++) {
memcpy(b + currentIndex, v[i], strlen(v[i]));
currentIndex += strlen(v[i]);
}
这样的事情,可能行不通,我没有测试过。
如果您想将b
用作字符串,则需要在结尾添加0
。
答案 3 :(得分:0)
试试这个:
std::vector<const char*> v;
v.push_back("abc");
v.push_back("def");
void* b = malloc(6);
int l = strlen(v[0]);
memcpy(b, v[0], l);
l = strlen(v[1]);
memcpy(b+l, v[1], l);
答案 4 :(得分:0)
这是我能想到的最像C ++的方式。它不使用任何C风格的字符串操作或内存管理功能,它尽可能安全。缺点是在没有实际需要的情况下分配和释放临时缓冲区。
此示例中使用了以下标头。
#include <cstddef>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
现在,第一个版本(我更喜欢)分配一个正确大小的缓冲区,并将其包装在std::unique_ptr<char[]>
中,然后调用者可以从中提取缓冲区并隐式地将其转换为void *
如果需要的话。
std::unique_ptr<char[]>
concatenate(const std::vector<const char *>& words)
{
std::string buffer {};
std::unique_ptr<char[]> dup_uptr {};
for (const auto word : words)
buffer += word;
dup_uptr.reset(new char[buffer.size() + 1]);
buffer.copy(dup_uptr.get(), buffer.size());
dup_uptr.get()[buffer.size()] = '\0';
return dup_uptr;
}
第二个版本将目标缓冲区及其大小作为参数,并在那里复制连接的字符串。如果缓冲区太小而且安全性也很低,这显然会失败,因为我们可能会犯错误并传递错误的缓冲区大小。为方便起见,它会返回一个指向字符串的char *
指针,如果缓冲区太小则返回nullptr
。
char *
concatenate(const std::vector<const char *>& words,
void *const dest,
const std::size_t size)
{
char * dest_chars = static_cast<char *>(dest);
std::string buffer {};
for (const auto word : words)
buffer += word;
// If we cannot copy the whole thing, copy nothing at all.
if (buffer.size() >= size)
return nullptr;
buffer.copy(dest_chars, buffer.size());
dest_chars[buffer.size()] = '\0';
return dest_chars;
}
这两个功能可以这样使用:
int
main()
{
const std::vector<const char*> vec {"abc", "def"};
// first version
{
auto concat = concatenate(vec);
std::cout << concat.get() << std::endl;
}
// second version
{
auto tempbuff = std::get_temporary_buffer<void>(100);
if (auto concat = concatenate(vec, tempbuff.first, tempbuff.second))
std::cout << concat << std::endl;
std::return_temporary_buffer(tempbuff.first);
}
return 0;
}