简体   繁体   中英

String to const char conversion using c_str() or toCharArray()?

I want to know more about programming and after a bit of googling I found how to convert a string to a const char.

String text1;

What I do not understand is why c_str() works,

const char *text2 = text1.c_str();

contrary to toCharArray()?

const char *text2 = text1.toCharArray();

or

const char text2 = text1.toCharArray();

The latter is more logical to me as I want to convert a string to a char, and then turn it into a const char. But that doesn't work because one is a string, the other is a char. The former, as I understand, converts the string to a C-type string and then turns it into a const char. Here, the string suddenly isn't an issue anymore oO

.

a) Why does it need a C-type string conversion and why does it work only then?

b) Why is the pointer needed?

c) Why does a simple toCharArray() not work?

.

Or do I do something terribly wrong?

Thanks heaps.

I am using PlatformIO with Arduino platform.

If you need to modify the returned c-style string in any way, or have it persist after you modify the original String , you should use toCharArray .

If you only need a null-terminated c-style string to pass as a read-only parameter to a function, use c_str .


Arduino reference for String.toCharArray()

Arduino reference for String.c_str()

The interface (and implementation) of toCharArray is shown below, from source

    void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
        { getBytes((unsigned char *)buf, bufsize, index); }

So your first issue is that you're trying to use it incorrectly. toCharArray will COPY the underlying characters of your String into a buffer that you provide. This must be extra space that you have allocated, either in a buffer on the stack, or in some other writable area of memory. You would do it like this.

String str = "I am a string!";
char buf[5];
str.toCharArray(buf, 5);
// buf is now "I am\0"

// or you can start at a later index, here index 5
str.toCharArray(buf, 5, 5);
// buf is now "a st\0"

// we can also change characters in the buffer
buf[1] = 'X';
// buf is now "aXst\0"

// modifying the original String does not invalidate the buffer
str = "Je suis une chaine!";
// buf is still "aXst\0"

This allows you to copy a string partially, or at a later index, or anything you want. Most importantly, this array you copy into is mutable. We can change it, and since it's a copy, it doesn't affect the original String we copied it from. This flexibility comes with a cost. First, we have to have a large enough buffer, which may not be known at compile time, and takes up memory. Second, that copying takes time to do.


But what if we're calling a function that just wants to read a c-style string as input? It doesn't need to modify it at all?

That's where c_str() comes in. The String object has an underlying c-string type array (yes, null terminator and all). c_str() simply returns a const char* to this array. We make it const so that we don't accidentally change it. An object's underlying data should not be changed by random functions outside of its control.

This is the ENTIRE code for c_str() :

const char* c_str() const { return buffer; }

You already know how to use it, but to illustrate a difference:

String str = "I am another string!";
const char* c = str.c_str();
// c[1] = 'X'; // error, cannot modify a const object

// modifying the original string may reallocate the underlying buffer
str = "Je suis une autre chaine!";
// dereferencing c now may point to invalid memory

Since c_str() simply returns the underlying data pointer, it's fast. But we don't want other functions to be allowed to modify this data, so it's const .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM