如何使用字符串文字优雅地初始化vector <char * =“”>?</char>

时间:2015-01-23 12:59:56

标签: c++ vector initialization cstring stdstring

问题来自于C ++ Primer第5版的练习:

  

编写程序以从char *指针列表中分配元素   将C风格的字符串转换为字符串向量。

---------------- Oringinal Question ------------

首先,我尝试以下方式:

vector<char *> vec = {"Hello", "World"};
vec[0][0] = 'h';

但是编译代码我收到警告:

temp.cpp:11:43: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
     vector<char *> vec = {"Hello", "World"};
                                           ^ 

运行./a.out我得到了

Segmentation fault (core dumped)

我认为这是因为我尝试写一个const char。所以我尝试另一种方式:

char s1[] = "Hello", s2[] = "World";
vector<char *> vec = {s1, s2};
vec[0][0] = 'h';

这次没关系。但这似乎有点单调乏味。有没有其他优雅的方法来初始化带字符串文字的向量?

3 个答案:

答案 0 :(得分:6)

这是一种方式:

template <size_t N>
void append_literal(std::vector<char*>& v, const char (&str)[N]) {
    char* p = new char[N];
    memcpy(p, str, N);
    v.push_back(p);
}

std::vector<char*> v;
append_literal(v, "Hello");
append_literal(v, "World");

请记住:

void clear(std::vector<char*>& v) {
    for (auto p : v) delete[] p;
}

虽然从问题的措辞来看,从语法上来说,无论如何它都是vector<const char*>,就好像它是vector<char*>一样(你不是在修改源时)复制,所以如果你可以修改源代码并不重要,所以我会像你刚才那样坚持练习:

std::vector<const char*> v{"Hello", "World!"};

答案 1 :(得分:6)

我认为char vs const char差异在此任务中无关紧要。

对于实际副本,请使用带有迭代器参数的填充构造函数:

vector<const char*> vc = {"hello","world"};
vector<string> vs(vc.begin(), vc.end());

查看working example

如果源中的可编辑字符需要,请使用您发布的第二个版本:

char s1[] = "Hello", s2[] = "World";
vector<char *> vec = {s1, s2};

补充:main argcargv的参数是很好的例子

  

指向C风格字符串的char *指针列表

请参阅how argc and argv get translated into a vector of string

答案 2 :(得分:0)

您可以尝试这样的事情:

// utility function to create char*'s
template<std::size_t Size>
char* make_rptr(const char (&s)[Size])
{
    char* rptr = new char[Size];
    std::strcpy(rptr, s);
    return rptr;
}

int main()
{
    // initialize vector
    std::vector<char*> v {make_rptr("hello"), make_rptr("world")};

    // use vector
    for(auto&& s: v)
        std::cout << s << '\n';

    // ...

    // remember to dealloacte
    for(auto&& s: v)
        delete[] s;
}