How to Get a Non-Const C String Back from a C++ String

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



Leave a reply



Submit