How to elegantly initialize vector<char *> with string literal?
Solution 1
Here's one way:
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");
Just remember to:
void clear(std::vector<char*>& v) {
for (auto p : v) delete[] p;
}
Although from the wording of the question, syntactically it's the same work either way if it was a vector<const char*>
as if it were a vector<char*>
anyway (you're not modifying the source when you're copy, so doesn't matter if you could modify the source), so I would stick to the exercise as if you just did:
std::vector<const char*> v{"Hello", "World!"};
Solution 2
I think the char
vs const char
difference doesn matter much in this task.
For the actual copy, use a fill constructor with iterator arguments:
vector<const char*> vc = {"hello","world"};
vector<string> vs(vc.begin(), vc.end());
See a working example.
If there's a need for editable chars in the source, just use the second version you posted:
char s1[] = "Hello", s2[] = "World";
vector<char *> vec = {s1, s2};
Supplement: The arguments of main, argc
and argv
, are a great example of
a list of char* pointers to C-style character strings
See how argc and argv get translated into a vector of string.
Related videos on Youtube
Warbean
Updated on September 14, 2022Comments
-
Warbean over 1 year
The problem comes from an exercise on 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.
----------------Oringinal Question------------
First I try the following somewhat direct way:
vector<char *> vec = {"Hello", "World"}; vec[0][0] = 'h';
But compiling the code I get a warning:
temp.cpp:11:43: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] vector<char *> vec = {"Hello", "World"}; ^
And running the ./a.out I get a
Segmentation fault (core dumped)
I think it is because I try to write to a const char. So I try another way:
char s1[] = "Hello", s2[] = "World"; vector<char *> vec = {s1, s2}; vec[0][0] = 'h';
It is OK this time. But it seems a little tedious. Is there any other elegant way to initialize a vector with string literal?
-
Borgleader over 9 yearsYou cannot change the contents of a string literal. Please use
std::vector<std::string>
(std::string
can be constructed from a string literal) live example -
Shafik Yaghmour over 9 yearsString literals are
array of n const char
, you can find more details here. The conversion was ok in C but is not allowed in C++, exactly because of the issue with attempting to modify them which is undefined behavior.
-
-
Warbean over 9 yearsOh that 's much more tedious than I expected. But thought-provoking. Thank you.
-
Wolf over 9 yearsWhy editable in the source array? This seems not to be covered explicitly in the task description, I guess it focuses on transferting C-strings in the new world of C++?
-
Warbean over 9 yearsI thought its usage could be more general. Maybe I need to focus on the transfering as you say.
-
Wolf over 9 years@Warbean I "found" a list of char* pointers you get for free :-)