[英]convert vector<string> into char** C++
I have a vector<std::string>
variable.我有一个
vector<std::string>
变量。 I need to pass it onto a method which accepts char**
as an input parameter.我需要将它传递给一个接受
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.我需要知道如何为 par2 和 par3 以及 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 是一个输出参数,我需要将它作为 std::string 返回。
sorry if i am very confusing or asking very basic questions.对不起,如果我很困惑或问非常基本的问题。
It is possible to solve the problem without copying out all the std::strings
as long as the function does not modify the passed in char**
.只要函数不修改传入的
char**
,就可以在不复制所有std::strings
情况下解决问题。 Otherwise I can see no alternative but to copy out everything into a new char**` structure (see second example) .否则我别无选择,只能将所有内容复制到新的 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('\0');
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.注意:已修改以提供更好的代码。
Galik's answer has a number of safety issues. Galik 的回答有许多安全问题。 Here is how I would do it in Modern C++:
这是我在现代 C++ 中的做法:
#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;
}
}
No messy memory management or nasty const_cast
s.没有凌乱的内存管理或讨厌的
const_cast
s。
Outputs:输出:
modifiable version
one
two
three
non-modifiable version
four
five
six
The top rated answers for this question expect you to pass in a size with your char** parameters.此问题评分最高的答案希望您传入带有 char** 参数的大小。 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.
但是在 method_to_be_called() 中,无法传递 par2 和 par3 的大小,因此这些 c 样式字符串列表可能期望以 null 结尾。 In other words the last string (char*) in the list of strings (char **) needs to be a null pointer.
换句话说,字符串列表 (char **) 中的最后一个字符串 (char*) 需要是空指针。 This is a common paradigm in many c libraries.
这是许多 c 库中的常见范例。
int method_to_be_called(char* par1, char ** par2, char ** par3, void* pRetValue);
The most expedient way around this is probably to go with a more c-style answer.解决此问题的最方便的方法可能是采用更 c 风格的答案。
//directly create char** par2
std::vector<std::string> par2Vect{"one", "two", "three"};
char ** par2 = (char**) malloc( sizeof(char*)*(par2Vect.size() + 1) );
for(size_t i = 0; i < par2Vect.size(); ++i)
{
par2[i] = strdup(par2Vect[i].c_str());
}
// set the last entry to null to signify the end of the list
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
free(par2[i]);
}
// free memory for outer char* array
free(par2);
I believe this is rather easy and can be done without too much of complexity.我相信这相当容易,并且可以在没有太多复杂性的情况下完成。
std::vector<std::string> vector = {"a", "std::vector", "of", "std::string"};
// Result char**.
char** result = new char*[vector.size()];
for (int index = 0; index < vector.size(); index++) {
result[index] = const_cast<char*>(vector[index].c_str());
}
// Use the result.
delete[] result;
// Deallocate the memory from heap after usage.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.