将vector 转换为char ** C ++

时间:2021-12-10 16:25:08

I have a vector<std::string> variable. I need to pass it onto a method which accepts char**as an input parameter.

我有一个vector 变量。我需要将它传递给一个接受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:

这个方法会在传递的patameter中自动调用。现在,我将在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的变量以及par2和par3的pRetValue.values在向量中可用,但最后一个参数pRetValue是一个输出参数,我需要将其作为std :: string返回。

sorry if i am very confusing or asking very basic questions.

对不起,如果我很困惑或提出非常基本的问题。

2 个解决方案

#1


22  

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**. Otherwise I can see no alternative but to copy out everything into a new char**` structure (see second example).

只要该函数不修改传入的char **,就可以在不复制所有std :: strings的情况下解决问题。否则,除了将所有内容复制到一个新的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.

注意:修改以提供更好的代码。

#2


14  

Galik's answer has a number of safety issues. Here is how I would do it in Modern C++:

Galik的答案有许多安全问题。以下是我在Modern 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_casts.

没有凌乱的内存管理或令人讨厌的const_casts。

Live on Coliru.

住在Coliru。

Outputs:

modifiable versiononetwothreenon-modifiable versionfourfivesix

#1


22  

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**. Otherwise I can see no alternative but to copy out everything into a new char**` structure (see second example).

只要该函数不修改传入的char **,就可以在不复制所有std :: strings的情况下解决问题。否则,除了将所有内容复制到一个新的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.

注意:修改以提供更好的代码。

#2


14  

Galik's answer has a number of safety issues. Here is how I would do it in Modern C++:

Galik的答案有许多安全问题。以下是我在Modern 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_casts.

没有凌乱的内存管理或令人讨厌的const_casts。

Live on Coliru.

住在Coliru。

Outputs:

modifiable versiononetwothreenon-modifiable versionfourfivesix