Если вам нужно каким-либо образом изменить возвращенную строку c -стила или сохранить ее после изменения исходного String
, вам следует использовать toCharArray
.
Если вам нужно только строка c с нулевым символом в конце для передачи функции в качестве параметра только для чтения, используйте c_str
.
ссылка Arduino для String.toCharArray()
Ссылка Arduino для String.c_str()
Интерфейс (и реализация) toCharArray
показан ниже, из source
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{ getBytes((unsigned char *)buf, bufsize, index); }
Итак, ваша первая проблема в том, что вы пытаетесь использовать его неправильно. toCharArray
превратит COPY основные символы вашего 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"
Это позволяет вам копировать строку частично, или с более поздним индексом, или что угодно. Самое главное, этот массив, в который вы копируете, является изменяемым. Мы можем изменить его, и, поскольку это копия, это не влияет на оригинал String
, с которого мы его скопировали. Эта гибкость имеет свою цену. Во-первых, у нас должен быть достаточно большой буфер, который может быть неизвестен во время компиляции и занимающий память. Во-вторых, это копирование требует времени.
Но что, если мы вызываем функцию, которая просто хочет прочитать строку стиля c в качестве ввода? Ему вообще не нужно его изменять?
Вот тут и появляется c_str()
. У объекта String
есть базовый массив типа c -string (да, нулевой терминатор и все). c_str()
просто возвращает const char*
в этот массив. Мы делаем это const
, чтобы случайно не изменить его. Базовые данные объекта не должны изменяться случайными функциями вне его контроля.
Это ВЕСЬ код для c_str()
:
const char* c_str() const { return buffer; }
Вы уже знаете, как его использовать, но Чтобы проиллюстрировать разницу:
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
Поскольку c_str()
просто возвращает базовый указатель данных, это быстро. Но мы не хотим, чтобы другим функциям было разрешено изменять эти данные, поэтому это const
.