如何用字符串文字优雅地初始化 vector<char *>?
How to elegantly initialize vector<char *> with string literal?
问题来自 C++ Primer 5th Edition 上的一个练习:
Write a program to assign the elements from a list of char* pointers
to C-style character strings to a vector of strings.
----------------原始问题------------
首先我尝试了以下比较直接的方法:
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';
这次可以了。但这似乎有点乏味。还有其他优雅的方法可以用字符串文字初始化向量吗?
这是一种方法:
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*>
一样(当你不修改源代码时,你不会修改源代码) 're copy, 所以如果你 可以 修改源代码也没关系),所以我会像你刚刚那样坚持练习:
std::vector<const char*> v{"Hello", "World!"};
我认为 char
与 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的参数argc
和argv
是很好的例子
a list of char* pointers to C-style character strings
您可以尝试这样的操作:
// 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;
}
问题来自 C++ Primer 5th Edition 上的一个练习:
Write a program to assign the elements from a list of char* pointers to C-style character strings to a vector of strings.
----------------原始问题------------
首先我尝试了以下比较直接的方法:
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';
这次可以了。但这似乎有点乏味。还有其他优雅的方法可以用字符串文字初始化向量吗?
这是一种方法:
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*>
一样(当你不修改源代码时,你不会修改源代码) 're copy, 所以如果你 可以 修改源代码也没关系),所以我会像你刚刚那样坚持练习:
std::vector<const char*> v{"Hello", "World!"};
我认为 char
与 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的参数argc
和argv
是很好的例子
a list of char* pointers to C-style character strings
您可以尝试这样的操作:
// 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;
}