使用 c_str() 或 toCharArray() 将字符串转换为 const char?

nol*_*its 3 c++ string arduino type-conversion char

我想了解更多有关编程的信息,经过一番谷歌搜索后,我发现了如何将字符串转换为 const char。

String text1;
Run Code Online (Sandbox Code Playgroud)

我不明白为什么 c_str() 起作用,

const char *text2 = text1.c_str();
Run Code Online (Sandbox Code Playgroud)

与 toCharArray() 相反?

const char *text2 = text1.toCharArray();
Run Code Online (Sandbox Code Playgroud)

或者

const char text2 = text1.toCharArray();
Run Code Online (Sandbox Code Playgroud)

后者对我来说更符合逻辑,因为我想将字符串转换为字符,然后将其转换为 const 字符。但这不起作用,因为一个是字符串,另一个是字符。前者,据我了解,将字符串转换为C类型字符串,然后将其转换为const char。在这里,字符串突然不再是问题了 oO

a) 为什么需要C类型的字符串转换以及为什么只有这样才可以工作?

b) 为什么需要指针?

c) 为什么简单的 toCharArray() 不起作用?

或者我做了什么非常错误的事情?

谢谢大家。

我正在将 PlatformIO 与 Arduino 平台一起使用。

Joh*_*eau 6

如果您需要以任何方式修改返回的 c 样式字符串,或者在修改原始字符串后使其保留String,则应使用toCharArray.

如果您只需要一个以 null 结尾的 c 样式字符串作为只读参数传递给函数,请使用c_str.


Arduino 参考String.toCharArray()

Arduino 参考String.c_str()

的接口(和实现)toCharArray如下所示,来自源码

    void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
        { getBytes((unsigned char *)buf, bufsize, index); }
Run Code Online (Sandbox Code Playgroud)

所以你的第一个问题是你试图错误地使用它。toCharArray会将您的底层字符复制String到您提供的缓冲区中。这必须是您分配的额外空间,无论是在堆栈的缓冲区中,还是在内存的其他可写区域中。你会这样做。

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"
Run Code Online (Sandbox Code Playgroud)

这允许您部分复制字符串,或在稍后的索引处复制字符串,或复制您想要的任何内容。最重要的是,您复制到的这个数组是可变的。我们可以更改它,并且由于它是副本,因此它不会影响String我们复制它的原始版本。这种灵活性是有代价的。首先,我们要有一个足够大的缓冲区,这个缓冲区在编译时可能是未知的,并且会占用内存。其次,复制需要时间。


但是,如果我们调用一个只想读取 C 风格字符串作为输入的函数怎么办?根本不需要修改吗?

这就是c_str()出现的地方。该String对象有一个底层的 c 字符串类型数组(是的,空终止符等等)。c_str()只是将 a 返回const char*到该数组。我们这样做const是为了避免意外改变它。对象的基础数据不应被其控制之外的随机函数更改。

这是完整的代码c_str()

const char* c_str() const { return buffer; }
Run Code Online (Sandbox Code Playgroud)

您已经知道如何使用它,但为了说明差异:

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
Run Code Online (Sandbox Code Playgroud)

由于c_str()只是返回底层数据指针,因此速度很快。但我们不希望允许其他函数修改此数据,因此它是const.