std :: vector <std :: string>到char * array </std :: string>

时间:2011-08-13 05:57:03

标签: c++ c stl stdvector

我有一个std::vector<std::string>,我需要使用C函数的参数来读取char* foo。我有seen howstd::string转换为char*。作为C++的新手,我正在尝试拼凑如何在向量的每个元素上执行此转换并生成char*数组。

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

6 个答案:

答案 0 :(得分:32)

您可以将std::transform用作:

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

这要求您将convert()实施为:

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

测试代码:

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];
}

输出:

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

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

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

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

但是如果你不想要这种灵活性,那么你可以使用这个const char *convert(const std::string & s) { return s.c_str(); } 函数:

std::vector<char*>

您必须将std::vector<const char*>更改为vs

现在转换后,如果您通过插入新字符串来更改char*,或者删除旧字符串中的旧字符串,那么vc中的所有delete vc[i]都可能无效。这是一个重点。另一个重点是,您不再需要在代码中使用{{1}}。

答案 1 :(得分:10)

您可以做的最好的事情是分配std::vector const char*与您的矢量大小相同的c_str()。然后,遍历向量的每个元素,调用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()); 以获取字符串数组并将其存储在数组的相应元素中。然后,您可以将指向该向量的第一个元素的指针传递给相关函数。

代码如下所示:

const char*

请注意,无法允许在从std::strings获取{{1}}的时间和调用C的时间之间调整原始字符串向量的大小-function。

答案 2 :(得分:7)

这应该有效:

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());
}

编辑:

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

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

再次编辑:

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

答案 3 :(得分:0)

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); }

如果函数null终止其参数,则在调用(s.begin(), s.end())之后可能没有意义。您可以进行后期处理以修复:

s = std::string(s.begin(), std::find(s.begin(), s.end(), '\0'));

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

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); });

答案 4 :(得分:-1)

const char *也与char *相同,只在const_ness中有所不同,你的接口方法接受const和非const字符串。

  

c_str()不返回const char吗?如果我这样做,那将是一个问题   需要一个char *?

是的,它返回一个const字符串,没有问题

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

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

答案 5 :(得分:-2)

向量的元素是stored contiguously,因此最好和最简单的方法是:

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