从字符串向量初始化二维数组的最简单方法是什么?

时间:2015-06-08 15:44:26

标签: c++ c++11 vector multidimensional-array

我有:

RetrofitSpiceService

我想要将其初始化,就好像我这样做

vector<string> myVector = {0};

myVector.push_back("first");
myVector.push_back("second");

char *list[] = ????

我知道我可以根据向量的大小和向量以及向量中最长字符串的大小(char *list[] = { "first", "second", NULL }; )开始分配内存但是我想看到我没有想到可能存在的东西更容易/更快。

2 个答案:

答案 0 :(得分:1)

如果遗留代码需要char **,那么要创建变量列表,您可以像在最初的问题中一样创建矢量。

之后,创建一个std::vector<char *>,其中指针是每个项目的向量中的指针。当然,您必须确保向量不会超出范围或调整大小。必须在创建std::vector<char *>之前完全“设置”。

此外,由于您确定遗留函数不会尝试更改发送给它的字符串,因此我们应该删除字符串的“常量”。

#include <vector>
#include <string>
#include <iostream>

void legacy_function(char **myList) 
{
     for (int i = 0; myList[i]; ++i)
          std::cout << myList[i] << "\n";
}

using namespace std;
int main()
{
    vector<string> myVector;
    myVector.push_back("first");
    myVector.push_back("second");
    //...
    // create the pointer vector
    vector<char *> myPtrVector;
    // add pointer to string to vector
    for (size_t i = 0; i < myVector.size(); ++i)
       myPtrVector.push_back(const_cast<char*>(myVector[i].c_str()));
    // stick the null at the end
    myPtrVector.push_back(NULL);
    // ...
    // call legacy function
    legacy_function(&myPtrVector[0]);
}  

基本上,我们在向量中创建了字符串,并创建了另一个存储指向字符串的指针的向量。

注意函数legacy_function需要char **,我们需要做的就是将它传递给指针向量中第一个元素的地址。

直播示例:http://ideone.com/77oNns

编辑:在代码组织方面,更好的方法是封装数组的创建,而不是让代码散布在程序的不同区域:

#include <vector>
#include <string>

class CharPtrPtr
{
   std::vector<std::string> m_args;
   std::vector<char *> m_argsptr;

   public:
       void add(const std::string& s) { m_args.push_back(s); }

       char ** create_argsPtr() 
       { 
          m_argsptr.clear();
          for (size_t i = 0; i < m_args.size(); ++i)
             m_argsptr.push_back(const_cast<char*>(m_args[i].c_str()));
          m_argsptr.push_back(NULL);
          return &m_argsptr[0]; 
       }

       char **get_argsPtr() { return m_argsptr.empty()?NULL:&m_argsptr[0]; }

       void clear_args() { m_args.clear(); m_argsptr.clear(); }
};


#include <iostream>

void legacy_function(char **myList) 
{
    for (int i = 0; myList[i]; ++i)
        std::cout << myList[i] << "\n";
}

int main()
{
    CharPtrPtr args;
    args.add("first");
    args.add("second");
    legacy_function(args.create_argsPtr());
}     

直播示例:http://coliru.stacked-crooked.com/a/834afa665f054a1f

答案 1 :(得分:0)

我试过这两种方式,

1.手动初始化

char *list[] = { (char*)&myVector[0][0], (char*)&myVector[1][0] };

2.在循环中初始化

char **list2 = new char*[ myVector.size() ];
for ( unsigned int i = 0; i < myVector.size(); ++i ) {
    list2[ i ] = (char*)&myVector[ i ][0];
}

但是这些列表只有指向向量中每个字符串的指针,并且实际上没有副本。如果更改字符串,您将看到列表中的更改。但是如果你清空向量,那么列表将有一个悬空指针。

3.如果您想要字符串的副本,

char **list = new char*[ myVector.size() ];
for ( unsigned int i = 0; i < myVector.size(); ++i ) {
    list[ i ] = new char[myVector[i].size()+1];
    strcpy( list[ i ], &myVector[i][0] );
}

我不会写这段代码,但是,你去..