将 vector<string> 转换为 char** C++
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26032039/
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
convert vector<string> into char** C++
提问by Mohamed Iqzas
I have a vector<std::string>
variable. I need to pass it onto a method which accepts char**
as an input parameter.
我有一个vector<std::string>
变量。我需要将它传递给一个接受char**
作为输入参数的方法。
how to do this ? If possible I need to pass a writable one.
这该怎么做 ?如果可能,我需要通过一个可写的。
Update 1:In a tool for creating a service method, i give parameters as std::vector, but it sets automatically the qualifier as &, which means my method definition generated by the tool will look as:
更新 1:在用于创建服务方法的工具中,我将参数指定为 std::vector,但它自动将限定符设置为 &,这意味着该工具生成的方法定义将如下所示:
std::string SvcImpl::myMethodname ( const std::string par1, const std::vector< std::string >& par2, const std::vector< std::string >& par3 )
{
}
This method gets called automatically with values in the patameter passed. Now from inside this method I'm going to call a method in a dll in a lib folder which looks like:
使用传递的参数表中的值自动调用此方法。现在,从这个方法内部,我将在 lib 文件夹中的 dll 中调用一个方法,如下所示:
int method_to_be_called(char* par1, char ** par2, char ** par3, void* pRetValue);
for par1 --> I'm passing (char*)par1.c_str()
对于 par1 --> 我正在传递 (char*)par1.c_str()
I need to know how to pass variables for par2 and par3 and for pRetValue. values for par2 and par3 are available in vector but the last parameter pRetValue is an output parameter that i need to return it as std::string.
我需要知道如何为 par2 和 par3 以及 pRetValue 传递变量。par2 和 par3 的值在向量中可用,但最后一个参数 pRetValue 是一个输出参数,我需要将它作为 std::string 返回。
sorry if i am very confusing or asking very basic questions.
对不起,如果我很困惑或问非常基本的问题。
回答by Galik
It is possible to solve the problem without copying out all the std::strings
as long as the function does not modifythe passed in char**
. Otherwise I can see no alternative but to copy out everything into a new char**` structure (see second example).
它可以解决问题,而所有复制出来std::strings
,只要功能不修改的传递char**
。否则我别无选择,只能将所有内容复制到新的 char**` 结构中(参见第二个示例)。
void old_func(char** carray, size_t size)
{
for(size_t i = 0; i < size; ++i)
std::cout << carray[i] << '\n';
}
int main()
{
std::vector<std::string> strings {"one", "two", "three"};
std::vector<char*> cstrings;
cstrings.reserve(strings.size());
for(size_t i = 0; i < strings.size(); ++i)
cstrings.push_back(const_cast<char*>(strings[i].c_str()));
// Do not change any of the strings here as that will
// invalidate the new data structure that relies on
// the returned values from `c_str()`
//
// This is not an issue after C++11 as long as you don't
// increase the length of a string (as that may cause reallocation)
if(!cstrings.empty())
old_func(&cstrings[0], cstrings.size());
}
EXAMPLE 2:If the function must modify the passed in data:
示例 2:如果函数必须修改传入的数据:
void old_func(char** carray, size_t size)
{
for(size_t i = 0; i < size; ++i)
std::cout << carray[i] << '\n';
}
int main()
{
{
// pre C++11
std::vector<std::string> strings {"one", "two", "three"};
// guarantee contiguous, null terminated strings
std::vector<std::vector<char>> vstrings;
// pointers to rhose strings
std::vector<char*> cstrings;
vstrings.reserve(strings.size());
cstrings.reserve(strings.size());
for(size_t i = 0; i < strings.size(); ++i)
{
vstrings.emplace_back(strings[i].begin(), strings[i].end());
vstrings.back().push_back('#include <iostream>
#include <string>
#include <vector>
void old_func(char** carray, std::size_t size)
{
for(std::size_t i(0); i < size; ++i)
std::cout << carray[i] << '\n';
}
void other_old_func(const char** carray, std::size_t size)
{
for(std::size_t i(0); i < size; ++i)
std::cout << carray[i] << '\n';
}
int main()
{
{
std::cout << "modifiable version\n";
std::vector<std::string> strings{"one", "two", "three"};
std::vector<char*> cstrings{};
for(auto& string : strings)
cstrings.push_back(&string.front());
old_func(cstrings.data(), cstrings.size());
std::cout << "\n\n";
}
{
std::cout << "non-modifiable version\n";
std::vector<std::string> strings{"four", "five", "six"};
std::vector<const char*> cstrings{};
for(const auto& string : strings)
cstrings.push_back(string.c_str());
other_old_func(cstrings.data(), cstrings.size());
std::cout << std::endl;
}
}
');
cstrings.push_back(vstrings.back().data());
}
old_func(cstrings.data(), cstrings.size());
}
{
// post C++11
std::vector<std::string> strings {"one", "two", "three"};
std::vector<char*> cstrings;
cstrings.reserve(strings.size());
for(auto& s: strings)
cstrings.push_back(&s[0]);
old_func(cstrings.data(), cstrings.size());
}
}
NOTE:Revised to provide better code.
注意:已修改以提供更好的代码。
回答by caps
Galik's answer has a number of safety issues. Here is how I would do it in Modern C++:
Galik 的回答有许多安全问题。这是我在现代 C++ 中的做法:
modifiable version
one
two
three
non-modifiable version
four
five
six
No messy memory management or nasty const_cast
s.
没有凌乱的内存管理或讨厌的const_cast
s。
Outputs:
输出:
int method_to_be_called(char* par1, char ** par2, char ** par3, void* pRetValue);
回答by Lon Risinger
The top rated answers for this question expect you to pass in a size with your char** parameters. But in method_to_be_called() there is no way to pass in a size for par2 and par3 so these lists of c-style strings probably expect to be null terminated. In other words the last string (char*) in the list of strings (char **) needs to be a null pointer. This is a common paradigm in many c libraries.
此问题评分最高的答案希望您传入带有 char** 参数的大小。但是在 method_to_be_called() 中,无法传递 par2 和 par3 的大小,因此这些 c 样式字符串列表可能期望以 null 结尾。换句话说,字符串列表 (char **) 中的最后一个字符串 (char*) 需要是空指针。这是许多 c 库中的常见范例。
//directly create char** par2
std::vector<std::string> par2Vect{"one", "two", "three"};
char ** par2 = new char*[par2Vect.size() + 1];
for(size_t i = 0; i < par2Vect.size(); ++i)
{
par2[i] = strdup(par2Vect[i].c_str());
}
par2[par2Vect.size()] = nullptr;
// call your library
method_to_be_called(..., par2,...);
// delete par2
for(size_t i = 0; i < par2Vect.size(); ++i)
{
// free memory for each c-style string
delete par2[i];
}
// free memory for outer char* array
delete par2;
The most expedient way around this is probably to go with a more c-style answer.
解决此问题的最方便的方法可能是采用更 c 风格的答案。
##代码##