如何将一个vector<string>转换为vector<char*>?

4

这与 如何将 vector<char*> 转换为 vector<string>/string 问题相反。

我有一些使用 vector<char*> 的旧例程,所以我需要转换我的 vector<string>

以下是我的解决方案:

std::vector<char*> charVec(strVec.size(),nullptr);
for (int i=0; i<strVec.size();i++) {
    charVec[i]= new char(strVec[i].size()+1); 
    charVec[i][strVec[i].copy(charVec[i], strVec[i].size())] = '\0';
}

这样做正确吗?

有更好的实现方法吗?


p.s. 当然,最后我有:

for (int i=0; i<strVec.size();i++) {
    delete charVec[i];
}

你有什么问题? - Anon Mail
1
你有问题吗?看起来你已经实现了它。 - kmdreko
1
这取决于新向量是否需要拥有它的字符串,或者它只需要对其他向量中的字符串进行临时查看。 - Galik
5个回答

6
这个的更快方法是:
std::vector<const char*> charVec(strVec.size(),nullptr);
for (int i=0; i<strVec.size();i++) {
    charVec[i]= strVec[i].c_str();
}

然后使用生成的向量。这将节省大量用于大型数据集的内存分配时间。


你的结果向量必须是 std::vector<const char*>const char* 不能赋值给 char* - MRB
谢谢,我已经更正了我的答案。我总是忘记c_str返回一个const指针。 - JeremiahB
c_str()的生命周期不允许你这样做,我觉得是吧? - worldterminator

4
为什么要为字符串分配新缓冲区?你正在将字符指针的vector传递给函数,并最终删除已分配的缓冲区。这意味着这些缓冲区是临时的,只要源vector(vector<string>)存在,就没有必要为它们分配内存。
你可以很容易地做到这一点:
std::vector<std::string> vec1 = { "1", "2", "3" };
std::vector<const char*> vec2;

vec2.resize(vec1.size(), nullptr);

std::transform(std::begin(vec1), std::end(vec1), std::begin(vec2), [&](const std::string& str)
{
    return str.c_str();
});

或者您可以将 vec2.resize() 替换为 vec2.reserve(),然后使用 std::back_inserter(vec2) 作为输出迭代器。 - Remy Lebeau
@RemyLebeau 当然,说得好。我忘记了std::back_inserter。谢谢提醒。 - MRB

4
您的new语句看起来不正确。您需要分配一个足够长以容纳字符串的char数组。您正在分配一个单独的char,其值是字符串的长度。我很惊讶您没有收到有关此问题的编译器警告。
请尝试这个:
std::vector<char*> charVec;
for (const auto &str : strVec) {
  char *charStr = new char[str.size() + 1];
  std::strcpy(charStr, str.c_str());
  charVec.push_back(charStr); 
}

这里唯一的缺点是,如果其中一个字符串包含了嵌入的空字符(null characters),则在其后面的内容都不会被复制。但我猜想,一个接受 char * 向量的函数很可能也不关心这个问题。

2
你可以简单地使用string::c_str()从std::string中获取字符串。在如何将std::string转换为const char*或char*?中了解更多信息。
或者你可以稍微修改函数的主体,但只有你知道这是否值得。
当然,正如ssell在评论中提到的那样,请记住,在使用这种方法时,您不需要破坏处理字符串!这是一种权衡,您避免了复制(很酷),但需要小心不要读取垃圾(如果删除字符串)。

我不建议使用std::string::c_str,因为它不安全。如果任何原始的std::string对象被销毁,那么char*字符串将变得无效。最好像他在问题中所做的那样复制数据,以及其他人在他们的答案中所做的那样。请参阅什么是std::string :: c_str()寿命? - ssell
@ssell说得很好,但我不会选择“不要触摸”指令,我更喜欢使用谨慎使用,我会进行更新! - gsamaras
1
如果他对作用域有严格的控制,那么你的答案就是最直接的。只是想提醒潜在的危险。 - ssell

0

vector<string>转换为vector<const char*>:使用c_str()

std::vector<const char*> charVec(strVec.size(), nullptr);
for (int i=0; i<strVec.size(); i++) {
    charVec[i] = strVec[i].c_str();
}

将 vector < string > 转换为 vector < char* >:使用 &x[0]

std::vector<char*> charVec(strVec.size(), nullptr);
for (int i=0; i<strVec.size(); i++) {
    charVec[i] = &strVec[i][0];
}

参考资料:如何将std::string转换为const char*或char*?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接