If you just want to pass a std::string
to a function that needs const char*
you can use
std::string str;
const char * c = str.c_str();
If you want to get a writable copy, like char *
, you can do that with this:
std::string str;
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0'; // don't forget the terminating 0
// don't forget to free the string after finished using it
delete[] writable;
Edit: Notice that the above is not exception safe. If anything between the new
call and the delete
call throws, you will leak memory, as nothing will call delete
for you automatically. There are two immediate ways to solve this.
boost::scoped_array
boost::scoped_array
will delete the memory for you upon going out of scope:
std::string str;
boost::scoped_array<char> writable(new char[str.size() + 1]);
std::copy(str.begin(), str.end(), writable.get());
writable[str.size()] = '\0'; // don't forget the terminating 0
// get the char* using writable.get()
// memory is automatically freed if the smart pointer goes
// out of scope
std::vector
This is the standard way (does not require any external library). You use std::vector
, which completely manages the memory for you.
std::string str;
std::vector<char> writable(str.begin(), str.end());
writable.push_back('\0');
// get the char* using &writable[0] or &*writable.begin()
You need to decode the bytes object to produce a string:
>>> b"abcde"
b'abcde'
# utf-8 is used here because it is a very common encoding, but you
# need to use the encoding your data is actually in.
>>> b"abcde".decode("utf-8")
'abcde'
Best Answer
For string literals, and only for string constants that come from literals, I would use
const char[]
. The main advantage ofstd::string
is that it has memory management for free, but that is not an issue with string literals.It is the actual type of the literal anyway, and it can be directly used in any API that requires either the old C style null terminated strings or the C++ strings (implicit conversion kicks in). You also get a compile time size implementation by using the array instead of the pointer.
Now, when defining function interfaces, and even if constants are intented to be passed in, I would prefer
std::string
rather thanconst char*
, as in the latter case size is lost, and will possibly need to be recalculated.Out of my own experience. I grew old of writting
.c_str()
on each and every call to the logging library (that used variable arguments) for literal strings with info/error messages.