你可以使用 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*>
在需要char**
的任何地方,您都可以使用&vc[0]
。
请注意,由于我们正在使用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
中插入新字符串或从中删除旧字符串来更改它,那么所有在 vc
中的 char*
可能会变得无效。这是一个重要的点。另一个重要的点是你不再需要在代码中使用 delete vc[i]
了。
convert
中的新代码抛出异常,那么这段代码就会泄漏。最好使用std::vector<char>
。 - Mankarsevs.size()
与vs
包含的各个字符串的长度毫无关系。此外,请阅读有关空终止字符串的内容。请注意,有效的c字符串必须以空终止符结尾,这有助于计算任何c字符串的长度。 - Nawaz您最好的选择是分配一个与您的vector大小相同的std::vector
,其中每个元素都是const char*
类型。然后遍历vector中的每个元素,调用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());
请注意,你不能在从std::strings
获取const char*
的时间和调用C函数的时间之间改变原始字符串向量的大小。
这应该可以正常工作:
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());
}
编辑:
以下是释放这些数据结构的方法,假设vec仍然具有正确数量的元素,如果您的C函数以某种方式修改了此数组,则可能需要以其他方式获取大小。
for(size_t i = 0; i < vec.size(); i++){
delete [] arr[i];
}
delete [] arr;
再次编辑:
如果你的C函数不修改字符串,那么复制这些字符串可能是不必要的。如果你能详细说明你的接口长什么样子,我们肯定能够提供更好的帮助。
delete[]
。 - Nicol Bolasfor
中的new
抛出异常,这将会泄漏。最好使用std::vector
。 - Mankarsestd::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); }
(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); });
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
}
返回本地对象并不被许多人接受,这个小例子仅供参考。
char*
,而不是你问题中提到的char**
。哪一个是正确的? - Luc Dantonfnames
参数不是const类型?对于一个初始化器修改其参数似乎很奇怪。 - Mankarsefnames
的所有权是否转移到了ModelInitialize
?(如果是这样:它必须如何分配?)调用代码是否打算从ModelInitialize
返回的Model
进行delete
,free
或其他释放操作?(如果是这样:它必须如何被释放?)fnames
必须是以空字符结尾的字符串吗?fnames
可以以哪些方式进行修改? - Mankarse