Can I get a non-const C string back from a C++ string?
I guess there is always strcpy
.
Or use char*
strings in the parts of your C++ code that must interface with the old stuff.
Or refactor the existing code to compile with the C++ compiler and then to use std:string
.
How to convert a std::string to const char* or char*
If you just want to pass a std::string
to a function that needs const char *
, you can use .c_str()
:
std::string str;
const char * c = str.c_str();
And if you need a non-const char *
, call .data()
:
std::string str;
char * c = str.data();
.data()
was added in C++17. Before that, you can use &str[0]
.
Note that if the std::string
is const
, .data()
will return const char *
instead, like .c_str()
.
The pointer becomes invalid if the string is destroyed or reallocates memory.
The pointer points to a null-terminated string, and the terminator doesn't count against str.size()
. You're not allowed to assign a non-null character to the terminator.
Is it bad to declare a C-style string without const? If so, why?
Yes, this declaration is bad practice, because it allows many ways of accidentally provoking Undefined Behavior by writing to a string literal, including:
cool[0] = 'k';
strcpy(cool, "oops");
On the other hand, this is perfectly fine, since it allocates a non-const array of chars:
char cool[] = "cool";
std::string to char*
It won't automatically convert (thank god). You'll have to use the method c_str()
to get the C string version.
std::string str = "string";
const char *cstr = str.c_str();
Note that it returns a const char *
; you aren't allowed to change the C-style string returned by c_str()
. If you want to process it you'll have to copy it first:
std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;
Or in modern C++:
std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
How to convert an std::string to C-style string
1) How do I convert std::string to a C-style string?
Simply call string.c_str()
to get a char const*
. If you need a mutable _C-style_ string then make a copy. The returned C string will be valid as long as you don't call any non-const function of string
.
2) Is there a way to get a C-style string from a stringstream?
There is, simply strstream.str().c_str()
. The returned C string will be valid only until the end of the expression that contains it, that means that is valid to use it as a function argument but not to be stored in a variable for later access.
3) Is there a way to use a C-style string directly (without using stringstreams) to construct a string with an integer variable in it?
There is the C way, using sprintf
and the like.
C++: Fastest method to return a C string
Return a const char*
instead of char*
. The const
in this context means "this pointer points to a constant pointee" - in other words, the caller cannot modify the returned string. This allows the compiler to place the strings in some memory location so the get_string()
function can just return addresses to those strings. If the caller needs to modify the returned string, they can allocate their own buffer and copy it (preferably via std::string
).
const char* get_string(char c) {
switch(c) {
case 'A': return "some string";
case 'B': return "some other string";
...
Why does calling c_str() on a function that returns a string not work?
SomeFunction().c_str()
gives you a pointer to a temporary(the automatic variable str
in the body of SomeFunction
). Unlike with references, the lifetime of temporaries isn't extended in this case and you end up with charArray
being a dangling pointer explaining the garbage value you see later on when you try to use charArray
.
On the other hand, when you do
string str_copy = SomeFunction();
str_copy
is a copy of the return value of SomeFunction()
. Calling c_str()
on it now gives you a pointer to valid data.
In C++, is a const method returning a pointer to a non-const object considered bad practice?
It depends on whether the non-const pointer is pointing to something inside the const object, or whether it is newly allocated memory that is meant to be variable.
Consider something that returned a copy of a string; it's fine for the returned copy to be non-const, even if the original string is const. The ownership of the copy is being passed from the method to the calling code; ensuring that the copy is appropriately destructed is now the calling code's problem (quite possibly a very minor problem).
However, it would be a very bad idea to return a non-const pointer to something from inside a const object.
Clean way to convert QString to char * (not const char* !!!!)
This is simple:
QByteArray array = string.toLocal8Bit();
char* buffer = array.data();
You can also use toLatin1
or toUtf8
instead of toLocal8Bit
. Note that neither of them can be queued with data
call. And toStdString().c_str()
is also invalid. This is because any QByteArray
or std::string
produced in such a way is temporary and will be destroyed immediately destroying char buffer with it. You need to store QByteArray
in a local variable while you're using the buffer.
Also note that Qt provides QByteArray
class to deal with char arrays. Generally there is no need to use char*
, you can do almost anything with QByteArray
.
Related Topics
Why Can't We Declare Object of a Class Inside the Same Class
How to Cheaply Assign C-Style Array to Std::Vector
Initializing a Ublas Vector from a C Array
Parse Int or Double Using Boost Spirit (Longest_D)
Mixing Templates with Polymorphism
C++ Issue with Cin and Ctrl + Z
What Does -Fpic Mean When Building a Shared Library
Recursion in C++ Factorial Program
Adding Signals/Slots (Qobject) to Qgraphicsitem: Performance Hit
Why Implicit Conversion Is Harmful in C++
How to Not Wait for a System() Command to Finish? (In C)
Allocating Struct with Variable Length Array Member