Short of (the obvious) building a C style string first then using that to create a std::string, is there a quicker/alternative/"better" way to initialize a string from a vector of chars?
-
6Can this be done without copying? In other words something which does the same thing as `std::vector
v2(std::move(v))` but with a `std::string` as the new object. – tobi_s Oct 02 '18 at 03:17
8 Answers
I think you can just do
std::string s( MyVector.begin(), MyVector.end() );
where MyVector is your std::vector.

- 257,169
- 86
- 333
- 562

- 2,868
- 22
- 27
-
2Except in VS2013 which asserts at runtime about invalid iterators, unless you set `_ITERATOR_DEBUG_LEVEL=1` (in which case it seems to work fine). – Cameron Sep 23 '14 at 22:39
With C++11, you can do std::string(v.data())
or, if your vector does not contain a '\0'
at the end, std::string(v.data(), v.size())
.

- 728
- 5
- 7
-
Even with C++98, I believe you can do std::string(&v[0]). This, of course, is if the vector is null-terminated. – Jamie Apr 16 '16 at 00:48
-
2@Jamie: By the way, in C++98, `string(&v[0], v.size())` should work also, but only after `assert(not v.empty());`, since if the vector is empty, both `v[0]` and `v.front()` would invoke undefined behavior. That, aside from the syntactic simplicity of not having to use the address-of operator, is the real benefit of C++11's `data()` function, which works even on an empty vector. – Adam H. Peterson Apr 25 '16 at 19:46
-
Very true. Unfortunately, my project is stuck on Visual Studio 2008 for the foreseeable future. Right about checking vector length first. – Jamie May 02 '16 at 17:51
-
1If vector does not contain a '\0', `std::string(v.data())` might lead a longer string. So do not use this way. – heLomaN Nov 20 '18 at 12:53
-
@heLomaN: What's wrong with `std::string(v.data(), v.size())`, which was explicitly mentioned in the answer for that exact reason? – Sz. Aug 13 '19 at 11:50
std::string s(v.begin(), v.end());
Where v is pretty much anything iterable. (Specifically begin() and end() must return InputIterators.)

- 12,682
- 2
- 39
- 53
I like Stefan’s answer (Sep 11 ’13) but would like to make it a bit stronger:
If the vector ends with a null terminator, you should not use (v.begin(), v.end()): you should use v.data() (or &v[0] for those prior to C++17).
If v does not have a null terminator, you should use (v.begin(), v.end()).
If you use begin() and end() and the vector does have a terminating zero, you’ll end up with a string "abc\0" for example, that is of length 4, but should really be only "abc".

- 71
- 1
- 2
-
-
Is there a performance difference between `(v.begin(), v.end())` and `(v.data())`? Will the latter be `O(n)`? – 김선달 Nov 30 '20 at 04:34
Just for completeness, another way is std::string(&v[0])
(although you need to ensure your string is null-terminated and std::string(v.data())
is generally to be preferred.
The difference is that you can use the former technique to pass the vector to functions that want to modify the buffer, which you cannot do with .data().

- 15,723
- 4
- 60
- 67
-
Why can't you use `data()` to modify the buffer? It looks to me like if you call `data()` on a non-const vector, it will return a `T *` (and if your vector is const, 'v[0]` would return a `T const &` anyway). – Adam H. Peterson Apr 25 '16 at 19:42
-
@AdamH.Peterson it seems to be an oversight in the standard. Std::vector's data has both const and non-const functions, whereas in the current standard, std::string has only a const function: http://en.cppreference.com/w/cpp/string/basic_string/data Note that C++17 adds a non-const version, so this may not be the case indefinitely - however, the current standard states "Modifying the character array accessed through data has undefined behavior." – Riot Apr 26 '16 at 16:48
-
That would be true if `v` were a string, but the target type is a string and `v` is a vector. (But it is nice to see that C++17 will give strings parity with vector.) – Adam H. Peterson Apr 26 '16 at 16:51
-
@AdamH.Peterson you're right of course. The question was answered a while ago, I'd assumed the whole question was about strings exclusively without checking. – Riot Apr 26 '16 at 17:44
vector<char> vec;
//fill the vector;
std::string s(vec.begin(), vec.end());

- 57
- 1
-
-
1C++11 string library template goes as follows default (1) string(); copy (2) string (const string& str); substring (3) string (const string& str, size_t pos, size_t len = npos); from c-string (4) string (const char* s); from buffer (5) string (const char* s, size_t n); fill (6) string (size_t n, char c); range (7) template
string (InputIterator first, InputIterator last); initializer list (8) string (initializer_list – TechCat May 13 '20 at 15:27il); move (9) string (string&& str) noexcept; we are following 7th template. -
Hi @TechCat! Please read up on [writing a good answer](https://stackoverflow.com/help/how-to-answer) before answering your next question. Enjoy your stay at SO! – Diggy. May 13 '20 at 15:49
-
-
Not sure why this was down voted, this is a perfectly acceptable answer. – Jamie Nicholl-Shelley Jan 04 '22 at 00:57
Just for code demonstration:
std::vector<char> vc {'l', 'o', 'v', 'e', '\0', '\0', '\0'};
std::string sCat(vc.cbegin(), vc.cend());
std::cout << sCat << "|---" << '\n';
std::cout << sCat.size() << "|---" << '\n';
std::cout << "------------" << '\n';
std::string sCat2(vc.data());
std::cout << sCat2 << "|---" << '\n';
std::cout << sCat2.size() << "|---" << '\n';
std::cout << "------------" << '\n';
std::string sCat3(&vc[0]);
std::cout << sCat3 << "|---" << '\n';
std::cout << sCat3.size() << "|---" << '\n';
std::cout << "------------" << '\n';
Output:
love|---
7|---
------------
love|---
4|---
------------
love|---
4|---
------------

- 2,565
- 22
- 23