How to construct a std::string from a std::vector char ?
Well, the best way is to use the following constructor:
template<class InputIterator> string (InputIterator begin, InputIterator end);
which would lead to something like:
std::vector<char> v;
std::string str(v.begin(), v.end());
std::vector char to std::string
Writing a null character at the end of a character vector will not magically create an std::string
. To create an actual std::string
, use something like:
std::string s = std::string(readBuffer.begin(), readBuffer.end());
You don't need to explicitly append the null character to the string, the std::string
constructor will do it for you.
Initialization of std::string from std::vector unsigned char causes error
std::string
has several constructors, some of which can be used to construct the string from a std::vector
, eg:
// using a char* pointer and a size...
std::string tmp2( reinterpret_cast<char*>(&some_vector[i]), j-i );
// using char* pointers as iterators...
std::string tmp2( &some_vector[i], &some_vector[j] );
// using vector iterators...
std::string tmp2( some_vector.begin()+i, some_vector.begin()+j );
Live Demo
How to construct a std::string from a std::vector string ?
C++03
std::string s;
for (std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i)
s += *i;
return s;
C++11 (the MSVC 2010 subset)
std::string s;
std::for_each(v.begin(), v.end(), [&](const std::string &piece){ s += piece; });
return s;
C++11
std::string s;
for (const auto &piece : v) s += piece;
return s;
Don't use std::accumulate
for string concatenation, it is a classic Schlemiel the Painter's algorithm, even worse than the usual example using strcat
in C. Without C++11 move semantics, it incurs two unnecessary copies of the accumulator for each element of the vector. Even with move semantics, it still incurs one unnecessary copy of the accumulator for each element.
The three examples above are O(n).
std::accumulate
is O(n²) for strings.
You could make
std::accumulate
O(n) for strings by supplying a
custom functor:std::string s = std::accumulate(v.begin(), v.end(), std::string{},
[](std::string &s, const std::string &piece) -> decltype(auto) { return s += piece; });Note that
s
must be a reference to non-const, the lambda return type
must be a reference (hencedecltype(auto)
), and the body must use+=
not+
.
C++20
In the current draft of what is expected to become C++20, the definition of std::accumulate
has been altered to use std::move
when appending to the accumulator, so from C++20 onwards, accumulate
will be O(n) for strings, and can be used as a one-liner:
std::string s = std::accumulate(v.begin(), v.end(), std::string{});
How to choose between `std::vector char ` and `std::string`?
What aspects need to be considered when making such a choice?
What is the input data and what is it going to be used for in the future? That would be a big consideration.
If the input data is not going to be used as a string in the future, it may be clearer in the future if you used a container as specified in the comments e.g. std::vector<std::byte>
.
Interpret a std::string as a std::vector of char_type?
If you make your template just for type const T&
and use the begin()
, end()
, etc, functions which both vector and string share then your code will work with both types.
How to push strings (char by char) into a vector of strings
It seems you need something like the following
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<std::vector<std::string>> v( 2 );
v[0].emplace_back( 1, 'z' );
v[1].emplace_back( 1, 'r' );
v[0][0].append( 1, ' ' );
v[1][0].append( 1, ' ' );
v[0][0].append( 1, 'x' );
v[1][0].append( 1, 'g' );
for ( const auto &item : v )
{
std::cout << item[0] << '\n';
}
return 0;
}
The program output is
z x
r g
Otherwise declare the vector like
std::vector<std::vector<char>> v;
For example
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<std::vector<char>> v( 2 );
v[0].emplace_back( 'z' );
v[1].emplace_back( 'r' );
v[0].emplace_back( 'x' );
v[1].emplace_back( 'g' );
for ( const auto &line : v )
{
for ( const auto &item : line )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
return 0;
}
Related Topics
Can the Use of C++11's 'Auto' Improve Performance
Default, Value and Zero Initialization Mess
Is #Pragma Once Part of the C++11 Standard
Use of the & Operator in C++ Function Signatures
What Is Going on with 'Gets(Stdin)' on the Site Coderbyte
Why Do I Need Double Layer of Indirection for MACros
How to Obtain C++ Type Names in a Constexpr Way
Can Someone Please Explain the "Indices Trick"
Boost Async_* Functions and Shared_Ptr'S
How to Implement a Natural Sort Algorithm in C++
5 Years Later, Is There Something Better Than the "Fastest Possible C++ Delegates"
Difference Between Rdtscp, Rdtsc:Memory and Cpuid/Rdtsc
Why Is Std::Min Failing When Windows.H Is Included
Using Std::Bind with Member Function, Use Object Pointer or Not for This Argument
Pure Virtual Functions May Not Have an Inline Definition. Why
Why Does the Most Negative Int Value Cause an Error About Ambiguous Function Overloads