相关文章推荐
高大的板栗  ·  为什么go语言的hello ...·  2 月前    · 
活泼的扁豆  ·  Microsoft Edge 开发工具协议 ...·  7 月前    · 
奔跑的骆驼  ·  页面未找到 - 七牛云·  1 年前    · 
跑龙套的小蝌蚪  ·  sql 列名无效_51CTO博客_列名无效·  1 年前    · 
销魂的海豚  ·  Gtest/Gmock实战之Gmock_51 ...·  1 年前    · 
朝气蓬勃的油条  ·  8-Oracle函数有哪些-阿里云开发者社区·  1 年前    · 
Code  ›  将vector<string>转换为char** C++开发者社区
string char vector char函数
https://cloud.tencent.com/developer/ask/sof/111332201
憨厚的金鱼
8 月前
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
提问

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

Stack Overflow用户
提问于 2014-09-25 06:29:50
EN

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

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

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

代码语言: javascript
复制
std::string SvcImpl::myMethodname ( const std::string par1, const std::vector<     std::string >& par2, const std::vector< std::string >& par3 )
}

使用传递的参数中的值自动调用此方法。现在,在这个方法中,我将在lib文件夹中调用dll中的一个方法,如下所示:

代码语言: javascript
复制
int method_to_be_called(char* par1, char ** par2, char ** par3, void* pRetValue);

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

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

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

4 31.7K 0 票数 39
EN
c++
c

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-09-25 06:47:39

只要函数 std::strings 不修改传递在 char** 中的,就可以在不复制所有 char** 的情况下解决这个问题。否则,我别无选择,只能将所有内容复制到一个新的char**‘structure (参见第二个示例) 中。

代码语言: javascript
复制
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());
}

示例2: 如果函数必须修改传入的数据:

代码语言: javascript
复制
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());
}

注意: 进行了修改,以提供更好的代码。

票数 41
EN

Stack Overflow用户

发布于 2016-01-29 21:54:54

Galik的回答有很多安全问题。以下是我如何在现代C++中这样做的:

代码语言: javascript
复制
#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;
}

没有混乱的内存管理或讨厌的 const_cast 。

住在Coliru。

产出:

代码语言: javascript
复制
modifiable version
three
non-modifiable version
six
票数 24
EN

Stack Overflow用户

发布于 2020-04-16 13:30:53

这个问题的最高评分答案期望您使用char**参数传递一个大小。但是在method_to_be_called()中,没有办法为par2和par3传递大小,因此这些c样式字符串的列表可能会以null结尾。换句话说,字符串列表(char **)中的最后一个字符串(char*)需要是空指针。这是许多c库中的一个常见范例。

代码语言: javascript
复制
int method_to_be_called(char* par1, char ** par2, char ** par3, void* pRetValue);

解决这一问题的最快捷的方法可能是采用更c式的答案。

代码语言: javascript
复制
//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)
 
推荐文章
高大的板栗  ·  为什么go语言的hello world程序编译后有2M那么大? -
2 月前
活泼的扁豆  ·  Microsoft Edge 开发工具协议 - Microsoft Edge Developer documentation | Microsoft Learn
7 月前
奔跑的骆驼  ·  页面未找到 - 七牛云
1 年前
跑龙套的小蝌蚪  ·  sql 列名无效_51CTO博客_列名无效
1 年前
销魂的海豚  ·  Gtest/Gmock实战之Gmock_51CTO博客_gtest gmock
1 年前
朝气蓬勃的油条  ·  8-Oracle函数有哪些-阿里云开发者社区
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号