将vector <string>转换为char**C++

Moh*_*zas 22 c c++

我有一个vector<std::string>变量.我需要将它传递给一个接受char**输入参数的方法.

这该怎么做 ?如果可能的话,我需要通过一个可写的.

更新1: 在创建服务方法的工具中,我将参数设置为std :: vector,但它自动将限定符设置为&,这意味着该工具生成的方法定义将如下所示:

std::string SvcImpl::myMethodname ( const std::string par1, const std::vector<     std::string >& par2, const std::vector< std::string >& par3 )
{

}
Run Code Online (Sandbox Code Playgroud)

传递的参数中的值会自动调用此方法.现在从这个方法里面我将在一个lib文件夹中调用一个方法,它看起来像:

int method_to_be_called(char* par1, char ** par2, char ** par3, void* pRetValue);
Run Code Online (Sandbox Code Playgroud)

对于par1 - >我正在传递(char*)par1.c_str()

我需要知道如何为par2和par3以及pRetValue传递变量.par2和par3的值在向量中可用,但最后一个参数pRetValue是一个输出参数,我需要将其作为std :: string返回.

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

Gal*_*lik 28

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());
}
Run Code Online (Sandbox Code Playgroud)

示例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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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


cap*_*aps 17

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

没有凌乱的记忆管理或讨厌的const_casts.

住在Coliru.

输出:

modifiable version
one
two
three


non-modifiable version
four
five
six
Run Code Online (Sandbox Code Playgroud)