Учебники

Arduino — Струны

Строки используются для хранения текста. Их можно использовать для отображения текста на ЖК-дисплее или в окне последовательного монитора Arduino IDE. Строки также полезны для хранения пользовательского ввода. Например, символы, которые пользователь вводит на клавиатуре, подключенной к Arduino.

В программировании Arduino есть два типа строк:

  • Массивы символов, которые совпадают со строками, используемыми в программировании на Си.
  • Arduino String, которая позволяет нам использовать строковый объект в эскизе.

В этой главе мы изучим строки, объекты и использование строк в эскизах Arduino. К концу главы вы узнаете, какой тип строки использовать в эскизе.

Массивы строк

Первый тип строки, который мы изучим, — это строка, представляющая собой последовательность символов типа char . В предыдущей главе мы узнали, что такое массив; последовательный ряд переменной того же типа, хранящийся в памяти. Строка — это массив переменных типа char.

Строка — это специальный массив, который имеет один дополнительный элемент в конце строки, который всегда имеет значение 0 (ноль). Это известно как «строка с нулевым символом в конце».

Пример массива символов строки

Этот пример покажет, как создать строку и распечатать ее в окне последовательного монитора.

пример

void setup() {
   char my_str[6]; // an array big enough for a 5 character string
   Serial.begin(9600);
   my_str[0] = 'H'; // the string consists of 5 characters
   my_str[1] = 'e';
   my_str[2] = 'l';
   my_str[3] = 'l';
   my_str[4] = 'o';
   my_str[5] = 0; // 6th array element is a null terminator
   Serial.println(my_str);
}

void loop() { 

}

В следующем примере показано, из чего состоит строка; массив символов с печатными символами и 0 в качестве последнего элемента массива, чтобы показать, что это конец строки. Строка может быть распечатана в окне Arduino IDE Serial Monitor с помощью Serial.println () и передачи имени строки.

Этот же пример можно написать более удобным способом, как показано ниже —

пример

void setup() {
   char my_str[] = "Hello";
   Serial.begin(9600);
   Serial.println(my_str);
}

void loop() {

}

В этом эскизе компилятор вычисляет размер массива строк, а также автоматически обнуляет нулевую строку. Массив, который состоит из шести элементов и состоит из пяти символов, за которыми следует ноль, создается точно так же, как и в предыдущем эскизе.

Манипулирование массивами строк

Мы можем изменить массив строк в эскизе, как показано на следующем рисунке.

пример

void setup() {
   char like[] = "I like coffee and cake"; // create a string
   Serial.begin(9600);
   // (1) print the string
   Serial.println(like);
   // (2) delete part of the string
   like[13] = 0;
   Serial.println(like);
   // (3) substitute a word into the string
   like[13] = ' '; // replace the null terminator with a space
   like[18] = 't'; // insert the new word
   like[19] = 'e';
   like[20] = 'a';
   like[21] = 0; // terminate the string
   Serial.println(like);
}

void loop() {

}

Результат

I like coffee and cake
I like coffee
I like coffee and tea

Эскиз работает следующим образом.

Создание и печать строки

В приведенном выше наброске создается новая строка, которая затем печатается для отображения в окне «Последовательный монитор».

Сокращение строки

Строка сокращается путем замены 14-го символа в строке нулевым завершающим нулем (2). Это элемент номер 13 в массиве строк, считая от 0.

Когда строка печатается, все символы печатаются до нового нулевого конечного нуля. Другие персонажи не исчезают; они все еще существуют в памяти, а строковый массив по-прежнему имеет тот же размер. Единственное отличие состоит в том, что любая функция, которая работает со строками, будет видеть строку только до первого нулевого терминатора.

Изменение слова в строке

Наконец, эскиз заменяет слово «торт» на «чай» (3). Сначала нужно заменить нулевой терминатор в позиции [13] пробелом, чтобы строка была восстановлена ​​в первоначально созданном формате.

Новые символы заменяют слово «торт» словом «торт» словом «чай». Это делается путем перезаписи отдельных символов. ‘E’ слова «торт» заменяется новым завершающим символом. В результате строка на самом деле заканчивается двумя нулевыми символами: исходным в конце строки и новым, заменяющим «e» в «cake». Это не имеет значения, когда печатается новая строка, потому что функция, которая печатает строку, прекращает печатать символы строки, когда она встречает первый нулевой терминатор.

Функции для манипулирования массивами строк

Предыдущий скетч манипулировал строкой вручную, получая доступ к отдельным символам в строке. Чтобы упростить манипулирование строковыми массивами, вы можете написать для этого свои собственные функции или использовать некоторые строковые функции из библиотеки языка Си .

String ()

Класс String, являющийся частью ядра начиная с версии 0019, позволяет использовать строки текста и манипулировать ими более сложными способами, чем массивы символов. Вы можете объединять строки, добавлять к ним, искать и заменять подстроки и многое другое. Это занимает больше памяти, чем простой массив символов, но это также более полезно.

Для справки: символьные массивы называются строками с маленьким ‘s’, а экземпляры класса String называются строками с большой буквы S. Обратите внимание, что константные строки, указанные в «двойных кавычках», обрабатываются как массивы символов, не экземпляры класса String

Charat ()

Доступ к определенному символу строки.

сравнить с()

Сравнивает две строки, проверяя, идет ли одна до или после другой, или равны ли они. Строки сравниваются посимвольно, используя значения символов ASCII. Это означает, например, что «а» предшествует «б», но после «А». Числа идут перед буквами.

CONCAT ()

Добавляет параметр в строку.

c_str ()

Преобразует содержимое строки как строку в стиле C с нулевым символом в конце. Обратите внимание, что это дает прямой доступ к внутреннему буферу String и должно использоваться с осторожностью. В частности, вы никогда не должны изменять строку через возвращаемый указатель. Когда вы изменяете объект String или когда он уничтожается, любой указатель, ранее возвращенный c_str (), становится недействительным и больше не должен использоваться.

EndsWith ()

Проверяет, заканчивается ли строка символами другой строки.

равна ()

Сравнивает две строки на равенство. Сравнение чувствительно к регистру, что означает, что строка «hello» не равна строке «HELLO».

equalsIgnoreCase ()

Сравнивает две строки на равенство. Сравнение не чувствительно к регистру, то есть String («привет») равен String («HELLO»).

GetBytes ()

Копирует символы строки в предоставленный буфер.

индекс()

Находит символ или строку в другой строке. По умолчанию поиск выполняется с начала строки, но также может начинаться с заданного индекса, что позволяет найти все экземпляры символа или строки.

LastIndexOf ()

Находит символ или строку в другой строке. По умолчанию он выполняет поиск с конца строки, но также может работать в обратном направлении по заданному индексу, что позволяет найти все экземпляры символа или строки.

длина ()

Возвращает длину строки в символах. (Обратите внимание, что это не включает завершающий нулевой символ.)

Удалить()

Изменить на месте строку, удаляющую символы из предоставленного индекса до конца строки или из предоставленного индекса в индекс плюс счетчик.

заменить ()

Функция String replace () позволяет заменить все экземпляры данного символа другим символом. Вы также можете использовать replace, чтобы заменить подстроки строки другой подстрокой.

резерв()

Функция String reserve () позволяет вам выделить буфер в памяти для работы со строками.

setCharAt ()

Устанавливает символ строки. Не влияет на индексы за пределами существующей длины строки.

начинается с()

Проверяет, начинается ли строка с символов другой строки.

toCharArray ()

Копирует символы строки в предоставленный буфер.

подстрока ()

Получить подстроку строки. Начальный индекс является включающим (соответствующий символ включен в подстроку), но необязательный конечный индекс является исключительным (соответствующий символ не включен в подстроку). Если конечный индекс опущен, подстрока продолжается до конца строки.

toInt ()

Преобразует действительную строку в целое число. Входная строка должна начинаться с целого числа. Если строка содержит нецелые числа, функция прекратит выполнение преобразования.

держаться на плаву()

Преобразует действительную строку в число с плавающей точкой. Входная строка должна начинаться с цифры. Если строка содержит нецифровые символы, функция прекратит выполнение преобразования. Например, строки «123.45», «123» и «123fish» преобразуются в 123.45, 123.00 и 123.00 соответственно. Обратите внимание, что «123,456» приближается к 123,46. Также обратите внимание, что значения с плавающей точкой имеют только 6-7 десятичных цифр и что более длинные строки могут быть обрезаны.

toLowerCase ()

Получить строчную версию String. Начиная с 1.0 toLowerCase () изменяет строку на месте, а не возвращает новую.

toUpperCase ()

Получите версию строки в верхнем регистре. Начиная с 1.0 toUpperCase () изменяет строку на месте, а не возвращает новую.

отделка()

Получите версию String с удаленными начальными и конечными пробелами. Начиная с 1.0, trim () изменяет строку на месте, а не возвращает новую.

В следующем наброске используются некоторые функции строки C.

пример

void setup() {
   char str[] = "This is my string"; // create a string
   char out_str[40]; // output from string functions placed here
   int num; // general purpose integer
   Serial.begin(9600);

   // (1) print the string
   Serial.println(str);

   // (2) get the length of the string (excludes null terminator)
   num = strlen(str);
   Serial.print("String length is: ");
   Serial.println(num);

   // (3) get the length of the array (includes null terminator)
   num = sizeof(str); // sizeof() is not a C string function
   Serial.print("Size of the array: ");
   Serial.println(num);

   // (4) copy a string
   strcpy(out_str, str);
   Serial.println(out_str);

   // (5) add a string to the end of a string (append)
   strcat(out_str, " sketch.");
   Serial.println(out_str);
   num = strlen(out_str);
   Serial.print("String length is: ");
   Serial.println(num);
   num = sizeof(out_str);
   Serial.print("Size of the array out_str[]: ");
   Serial.println(num);
}

void loop() {

}

Результат

This is my string
String length is: 17
Size of the array: 18
This is my string
This is my string sketch.
String length is: 25
Size of the array out_str[]: 40

Эскиз работает следующим образом.

Распечатать строку

Вновь созданная строка печатается в окне Serial Monitor, как было сделано в предыдущих эскизах.

Получить длину строки

Функция strlen () используется для получения длины строки. Длина строки указана только для печатных символов и не содержит нулевого терминатора.

Строка содержит 17 символов, поэтому мы видим 17 напечатанных в окне Serial Monitor.

Получить длину массива

Оператор sizeof () используется для получения длины массива, который содержит строку. Длина включает нулевой терминатор, поэтому длина на единицу больше длины строки.

sizeof () выглядит как функция, но технически это оператор. Он не является частью библиотеки C-строк, но использовался в эскизе, чтобы показать разницу между размером массива и размером строки (или длиной строки).

Копировать строку

Функция strcpy () используется для копирования строки str [] в массив out_num []. Функция strcpy () копирует вторую строку, переданную ей, в первую строку. Копия строки теперь существует в массиве out_num [], но занимает всего 18 элементов массива, поэтому у нас по-прежнему есть 22 свободных элемента char в массиве. Эти свободные элементы находятся после строки в памяти.

Строка была скопирована в массив, чтобы у нас было дополнительное пространство в массиве для использования в следующей части скетча, которая добавляет строку в конец строки.

Добавить строку к строке (объединить)

Эскиз соединяет одну строку с другой, что называется конкатенацией. Это делается с помощью функции strcat (). Функция strcat () помещает вторую переданную ей строку в конец первой переданной ей строки.

После объединения длина строки печатается, чтобы показать длину новой строки. Длина массива затем печатается, чтобы показать, что у нас есть строка длиной 25 символов в массиве длиной 40 элементов.

Помните, что строка длиной 25 символов на самом деле занимает 26 символов массива из-за нулевого завершающего нуля.

Границы массива

При работе со строками и массивами очень важно работать в пределах строк или массивов. В примере эскиза был создан массив длиной 40 символов, чтобы выделить память, которая может быть использована для работы со строками.

Если массив был сделан слишком маленьким, и мы попытались скопировать в него строку, превышающую массив, строка будет скопирована в конец массива. Память за концом массива может содержать другие важные данные, используемые в эскизе, которые затем будут перезаписаны нашей строкой. Если память за концом строки будет переполнена, это может привести к аварийному завершению эскиза или непредвиденному поведению.