convert vector into char** C++

前端 未结 3 1858
慢半拍i
慢半拍i 2020-11-27 20:24

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

how to do this ? If

3条回答
  •  心在旅途
    2020-11-27 20:49

    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).

    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 strings {"one", "two", "three"};
        std::vector cstrings;
        cstrings.reserve(strings.size());
    
        for(size_t i = 0; i < strings.size(); ++i)
            cstrings.push_back(const_cast(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:

    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 strings {"one", "two", "three"};
    
            // guarantee contiguous, null terminated strings
            std::vector> vstrings;
    
            // pointers to rhose strings
            std::vector 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 strings {"one", "two", "three"};
    
            std::vector 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.

提交回复
热议问题