C++ std::vector<std::string> 到 char* 数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7048888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:24:16  来源:igfitidea点击:

std::vector<std::string> to char* array

c++cstlstdvector

提问by Christopher DuBois

I have a std::vector<std::string>that I need to use for a Cfunction's argument that reads char* foo. I have seenhowto convert a std::stringto char*. As a newcomer to C++, I'm trying to piece together how to perform this conversion on each element of the vector and produce the char*array.

我有一个std::vector<std::string>我需要用于C读取char* foo. 我已经看到如何将 a 转换std::stringchar*. 作为 的新手C++,我正在尝试拼凑如何对向量的每个元素执行此转换并生成char*数组。

I've seen several closely related SO questions, but most appear to illustrate ways to go the other direction and create std::vector<std::string>.

我已经看到了几个密切相关的 SO 问题,但大多数似乎说明了走向另一个方向并创建std::vector<std::string>.

回答by Nawaz

You can use std::transformas:

您可以std::transform用作:

std::transform(vs.begin(), vs.end(), std::back_inserter(vc), convert);  

Which requires you to implement convert()as:

这要求您实现convert()为:

char *convert(const std::string & s)
{
   char *pc = new char[s.size()+1];
   std::strcpy(pc, s.c_str());
   return pc; 
}


Test code:

测试代码:

int main() {
       std::vector<std::string>  vs;
       vs.push_back("std::string");
       vs.push_back("std::vector<std::string>");
       vs.push_back("char*");
       vs.push_back("std::vector<char*>");
       std::vector<char*>  vc;

       std::transform(vs.begin(), vs.end(), std::back_inserter(vc), convert);   

       for ( size_t i = 0 ; i < vc.size() ; i++ )
            std::cout << vc[i] << std::endl;

       for ( size_t i = 0 ; i < vc.size() ; i++ )
            delete [] vc[i];
}

Output:

输出:

std::string
std::vector<std::string>
char*
std::vector<char*>

Online demo : http://ideone.com/U6QZ5

在线演示:http: //ideone.com/U6QZ5

You can use &vc[0]wherever you need char**.

您可以&vc[0]在任何需要的地方使用char**

Note that since we're using newto allocate memory for each std::string(in convertfunction), we've to deallocate the memory at the end. This gives you flexibility to change the vector vs; you can push_backmore strings to it, delete the existing one from vs, and vc(i.e vector<char*>will still be valid!

请注意,由于我们使用new为每个std::string(在convert函数中)分配内存,我们必须在最后释放内存。这使您可以灵活地更改向量vs;您可以添加push_back更多字符串,从 , 中删除现有字符串vs,并且vc(即vector<char*>仍然有效!

But if you don't want this flexibility, then you can use this convertfunction:

但是如果你不想要这种灵活性,那么你可以使用这个convert函数:

const char *convert(const std::string & s)
{
   return s.c_str();
}

And you've to change std::vector<char*>to std::vector<const char*>.

并且您必须更改std::vector<char*>std::vector<const char*>.

Now after the transformation, if you change vsby inserting new strings, or by deleting the old ones from it, then all the char*in vcmight become invalid. That is one important point. Another important point is that, you don't need to use delete vc[i]in your code anymore.

现在转换后,如果vs通过插入新字符串或从中删除旧字符串进行更改,则所有输入char*vc可能无效。这是很重要的一点。另一个重要的一点是,您不再需要delete vc[i]在代码中使用。

回答by Nicol Bolas

The best you can do is allocate an std::vectorof const char*the same size as your vector. Then, walk each element of the vector, calling c_str()to get the string array and storing it the corresponding element of the array. Then you can pass the pointer to the first element of this vector to the function in question.

你能做的最好的是一个分配std::vectorconst char*大小相同的载体。然后,遍历向量的每个元素,调用c_str()获取字符串数组并将其存储在数组的对应元素中。然后,您可以将指向此向量第一个元素的指针传递给相关函数。

The code would look like this:

代码如下所示:

std::vector<const char *> cStrArray;
cStrArray.reserve(origVector.size());
for(int index = 0; index < origVector.size(); ++index)
{
  cStrArray.push_back(origVector[index].c_str());
}

//NO RESIZING OF origVector!!!!

SomeCFunction(&cStrArray[0], cStrArray.size());

Note that you cannotallow the original vector of strings to be resized between the time you fetch the const char*s from the std::strings, and the time you call the C-function.

请注意,你不能让琴弦的原始矢量的时间之间进行调整,您将获取const char*从S std::strings,和一次调用C函数。

回答by GWW

This should work:

这应该有效:

char ** arr = new char*[vec.size()];
for(size_t i = 0; i < vec.size(); i++){
    arr[i] = new char[vec[i].size() + 1];
    strcpy(arr[i], vec[i].c_str());
}

EDIT:

编辑:

Here's how you would free these data structures assuming vec still has the correct number of elements, if your C function modifies this array somehow you may need to get the size another way.

以下是假设 vec 仍然具有正确数量的元素的情况下如何释放这些数据结构,如果您的 C 函数以某种方式修改了这个数组,您可能需要以另一种方式获取大小。

for(size_t i = 0; i < vec.size(); i++){
    delete [] arr[i];
}
delete [] arr;

EDIT Again:

再次编辑:

It may not be necessary to copy the strings if your C function does not modify the strings. If you can elaborate on what your interface looks like I'm sure we could provide you with better help.

如果您的 C 函数不修改字符串,则可能不需要复制字符串。如果您能详细说明您的界面是什么样的,我相信我们可以为您提供更好的帮助。

回答by Luc Danton

A C++0x solution, where elements of std::stringare guaranteed to be stored contiguously:

C++0x 解决方案,其中 的元素std::string保证连续存储:

std::vector<std::string> strings = /* from somewhere */;
int nterms = /* from somewhere */;

// using std::transform is a possibility depending on what you want
// to do with the result of the call
std::for_each(strings.begin(), string.end(), [nterms](std::string& s)
{ ModelInitialize(&s[0], nterms); }

If the function null terminates its argument, then after the call (s.begin(), s.end())might not be meaningful. You can post-process to fix that:

如果函数 null 终止其参数,则调用之后(s.begin(), s.end())可能没有意义。您可以进行后处理以解决该问题:

s = std::string(s.begin(), std::find(s.begin(), s.end(), '
typedef std::unique_ptr<char[]> pointer;
std::vector<pointer> args;
std::transform(strings.begin(), strings.end()
               , std::back_inserter(args)
               , [](std::string const& s) -> pointer
{
    pointer p(new char[s.size()]);
    std::copy(s.begin(), s.end(), &p[0]);
    return p;
});

std::for_each(args.begin(), args.end(), [nterms](pointer& p)
{ ModelInitialize(p.get(), nterms); });
'));

A more elaborate version that separately copies each string into a char[]:

一个更复杂的版本,将每个字符串分别复制到一个char[]

const char*a="something";
////whatever it is here
const char* retfunc(const char*a)
{
   char*temp=a;
   //process then return temp
}

回答by Marc

const char* is also the same as char*, only different in the const_ness, your interface method accepts both const and non-const string.

const char* 也与 char* 相同,只是 const_ness 不同,您的接口方法接受 const 和非常量字符串。

Doesn't c_str() return a const char? Will that be a problem if I just need a char*?

c_str() 不返回一个常量字符吗?如果我只需要一个字符*,那会不会有问题?

Yes, it returns a const string and no there should no problem

是的,它返回一个常量字符串,不应该没有问题

std::vector<char> v;
char* c = &v[0];

Returning a local object is n't accepted by many people andthis tiny example is provided as an as-is.

许多人不接受返回本地对象,这个小例子按原样提供。

回答by user1438233

The elements of a vector are stored contiguously, so the best and easy way is:

向量的元素是连续存储的,所以最好和最简单的方法是:

##代码##