这是大多数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;
}
更好的问题:你为什么要使用'字符*'和'malloc'在C++? – CoryKramer 2014-10-04 16:53:21
你很困惑。你的矢量大小为2,包含两个指针。你不需要六个字节的两个指针,你需要16个(假设你在一个64位系统上)。 – PSkocik 2014-10-04 16:53:23
@PSkocik他想把'const char *'s的字符串放到'b'中,而不是指针本身。 – BWG 2014-10-04 16:54:05