Преобразование строки в константный символ с помощью c_str () или toCharArray ()? - PullRequest
0 голосов
/ 28 марта 2020

Я хочу узнать больше о программировании, и после небольшого поиска в Google я нашел, как преобразовать строку в константный символ.

String text1;

Что я не понимаю, так это почему c_str () работает,

const char *text2 = text1.c_str();

в отличие от toCharArray ()?

const char *text2 = text1.toCharArray();

или

const char text2 = text1.toCharArray();

Последнее мне более логично, так как я хочу преобразовать строку в символ , а затем превратить его в const char. Но это не работает, потому что один - строка, другой - символ. Первый, как я понимаю, преобразует строку в строку типа C, а затем превращает ее в const char. Здесь строка внезапно перестает быть проблемой oO

.

a) Зачем нужно преобразование строки типа C и почему она работает только тогда?

б) Зачем нужен указатель?

c) Почему не работает простой toCharArray ()?

.

Или я делаю что-то ужасно не так?

Спасибо, куча.

Я использую PlatformIO с платформой Arduino.

1 Ответ

1 голос
/ 28 марта 2020

Если вам нужно каким-либо образом изменить возвращенную строку 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.

...