2014-10-04 51 views
0

我有一个std::vector<const char*> v矢量完全用字符串启动。我如何将它复制到初始化的void*如何将std :: vector <const char*>复制到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? 
} 

谢谢通过沿着每一次的字符串长度移动鼠标指针矢量

+1

更好的问题:你为什么要使用'字符*'和'malloc'在C++? – CoryKramer 2014-10-04 16:53:21

+0

你很困惑。你的矢量大小为2,包含两个指针。你不需要六个字节的两个指针,你需要16个(假设你在一个64位系统上)。 – PSkocik 2014-10-04 16:53:23

+0

@PSkocik他想把'const char *'s的字符串放到'b'中,而不是指针本身。 – BWG 2014-10-04 16:54:05

回答

3

您可以使用基于范围的for语句。例如

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]; 
+0

我得到了做指针算术的警告,但它的工作原理。所以谢谢。 – cody 2014-10-04 17:07:32

+0

@cody查看我更新的帖子。您必须将指针转换为char * – 2014-10-04 17:12:18

0

迭代。

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

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); 
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; 
} 
相关问题