Меню Рубрики

Arduino работа со строками

Содержание

  • Уроки
  • Программирование
  • Строки и массивы символов

Строки

Строка (String), как понятно из названия, это совокупность символов. По сути строка это одномерный массив типа данных char, про массивы мы уже недавно говорили и вы должны понять, о чём идёт речь. Как и в случае с массивом символов, к каждому элементу строки можно обратиться при помощи квадратных скобок. Основным отличием строки от массива символов является тот факт, что строка – динамический массив, у которого не нужно указывать размер. Также строка является не просто типом данных, а объектом, объектом очень мощного класса String.

Давайте рассмотрим большой пример, из которого будет понятно, как объявить строку и как с ней работать, а также учтены некоторые тонкости:

Как вы могли заметить, строки можно объявлять большим количеством способов, а также буквально складывать строки, как числа, оператором +. Я уже говорил, что строки являются объектами класса String, и у этого класса есть огромное количество удобных методов по работе со строками, далее мы их все рассмотрим с некоторыми примерами. Но для начала запомните вот что: строки – очень тяжёлый инструмент, очень медленный и занимающий кучу памяти: уже просто само наличие строк (от одной и более) в прошивке занимает +5% Flash памяти, т.к. подключается сам “инструмент” – класс String. Для небольших проектов это не страшно, памяти всегда будет навалом.

Инструменты для String

Итак, методы для работы со строками. Как и все методы, они применяются к своим объектам (к строкам) через точку. В рассмотренных ниже примерах строка называется myString.

myString.charAt(index);

Возвращает элемент строки myString под номером index. Аналог – myString[index];

myString.setCharAt(index, val);

Записывает в строку myString символ val на позицию index. Аналог – myString[index] = val;

myString.concat(value);

Присоединяет value к строке (value может иметь любой численный тип данных). Возвращает true при успешном выполнении, false при ошибке. Аналог – сложение, myString + value;

myString.endsWith(myString2);

Проверяет, заканчивается ли myString символами из myString2. В случае совпадения возвращает true

myString.startsWith(myString2);

Проверяет, начинается ли myString символами из myString2. В случае совпадения возвращает true

myString.equals(myString2);

Возвращает true, если myString совпадает с myString2. Регистр букв важен

myString.equalsIgnoreCase (myString2);

Возвращает true, если myString совпадает с myString2. Регистр букв неважен

myString.indexOf(val);
myString.indexOf(val, from);

Ищет и возвращает номер (позицию) значения val в строке, ищет слева направо, возвращает номер первого символа в совпадении. val может быть char или String, то есть ищем в строке другую строку или символ. Можно искать, начиная с позиции from. В случае, когда не может найти val в строке, возвращает -1.

myString.lastIndexOf(val);
myString.lastIndexOf(val, from);

Ищет и возвращает номер (позицию) значения val в строке, ищет справа налево, возвращает номер последнего символа в совпадении. val может быть char или String, то есть ищем в строке другую строку или символ. Можно искать, начиная с позиции from. В случае, когда не может найти val в строке, возвращает -1.

myString.length();

Возвращает длину строки в количестве символов

myString.remove(index);
myString.remove(index, count);

Удаляет из строки символы, начиная с index и до конца, либо до указанного count

myString.replace(substring1, substring2);

В строке myString заменяет последовательность символов substring1 на substring2.

myString.reserve(size);

Зарезервировать в памяти количество байт size для работы со строкой

myString.c_str();

Преобразовывает строку в “СИ” формат (null-terminated string) и возвращает указатель на полученную строку

myString.trim();

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

myString.substring(from);
myString.substring(from, to);

Возвращает кусок строки, содержащейся в myString начиная с позиции from и до конца, либо до позиции to

myString.toCharArray(buf, len);

Раскидывает строку в массив – буфер buf (типа char []) с начала и до длины len

myString.getBytes(buf, len);

Копирует указанное количество символов len (вплоть до unsigned int) в буфер buf (byte [])

myString.toFloat();

Возвращает содержимое строки в тип данных float

myString.toDouble();

Возвращает содержимое строки в тип данных double

myString.toInt();

Возвращает содержимое строки в тип данных int

myString.toLowerCase();

Переводит все символы в нижний регистр. Было ААААА – станет ааааа

myString.toUpperCase();

Переводит все символы в верхний регистр. Было ааааа – станет ААААА

Длина строки

Небольшой комментарий по поводу длины строки: мы можем узнать длину строки двумя способами, при помощи оператора sizeof() и метода length(). Давайте разберём отличия между ними:

Оператор sizeof вернёт размер строки в байтах. Строка содержит “нулевой символ” на конце, этот символ тоже весит один байт, соответственно оператор вернёт число 6. Метод length возвращает длину строки в количестве символов, не считая завершающий нулевой, поэтому результат будет 5.

F() macro

Строки являются очень тяжёлым с точки зрения использования памяти инструментом, ведь текст в строке хранится в оперативной памяти микроконтроллера, а её не так уж и много. Есть готовый инструмент, позволяющий удобно хранить текстовые данные во Flash памяти микроконтроллера. Этот способ хорош для вывода фиксированных текстовых данных, например, в монитор порта:

Строка “Hello, World!” будет записана во Flash память и не займёт 14 байт (13 + нулевой) в оперативной.

Массивы символов

Массивы символов, они же char array, являются ещё одним способом работы с текстовыми данными. Этот вариант имеет гораздо меньше возможностей по работе с текстом, но зато занимает меньше места в памяти (не используется элемент String) и работает значительно быстрее. К массиву символов применяются те же правила, какие работают для обычных массивов. Рассмотрим пример, в котором объявим массив символов, поработаем с ним, и выведем в порт:

Читайте также:  Домашнее вино из фруктов простой рецепт

В отличие от строк, массивы символов нельзя:

Длина строки char array

Для определения длины текста можно использовать оператор strlen, который возвращает количество символов в массиве. Сравним его работу с оператором sizeof:

Здесь оператор sizeof вернул количество байт, занимаемое массивом. Массив я специально объявил с размером бОльшим, чем содержащийся в нём текст. А вот оператор strlen посчитал и вернул количество символов, которые идут с начала массива и до нулевого символа в конце текста.

Массив строк

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

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

Экономия памяти

“Строки” в массиве строк тоже хранятся в оперативной памяти, что не очень здорово. Ещё больше не здорово то, что применить рассмотренный F() macro к ним нельзя, потому что фактически это не строки. То есть вот такой код приведёт к ошибке:

Как же быть? Массив строк можно сохранить в PROGMEM, программной памяти микроконтроллера, то есть во Flash. Вот такую конструкцию можно использовать как шаблон:

Да, сложно и громоздко, но при большом объёме текстовых данных это может спасти проект!

  • Уроки
  • Программирование
  • Строки и массивы символов

Строки

Строка (String), как понятно из названия, это совокупность символов. По сути строка это одномерный массив типа данных char, про массивы мы уже недавно говорили и вы должны понять, о чём идёт речь. Как и в случае с массивом символов, к каждому элементу строки можно обратиться при помощи квадратных скобок. Основным отличием строки от массива символов является тот факт, что строка – динамический массив, у которого не нужно указывать размер. Также строка является не просто типом данных, а объектом, объектом очень мощного класса String.

Давайте рассмотрим большой пример, из которого будет понятно, как объявить строку и как с ней работать, а также учтены некоторые тонкости:

Как вы могли заметить, строки можно объявлять большим количеством способов, а также буквально складывать строки, как числа, оператором +. Я уже говорил, что строки являются объектами класса String, и у этого класса есть огромное количество удобных методов по работе со строками, далее мы их все рассмотрим с некоторыми примерами. Но для начала запомните вот что: строки – очень тяжёлый инструмент, очень медленный и занимающий кучу памяти: уже просто само наличие строк (от одной и более) в прошивке занимает +5% Flash памяти, т.к. подключается сам “инструмент” – класс String. Для небольших проектов это не страшно, памяти всегда будет навалом.

Инструменты для String

Итак, методы для работы со строками. Как и все методы, они применяются к своим объектам (к строкам) через точку. В рассмотренных ниже примерах строка называется myString.

myString.charAt(index);

Возвращает элемент строки myString под номером index. Аналог – myString[index];

myString.setCharAt(index, val);

Записывает в строку myString символ val на позицию index. Аналог – myString[index] = val;

myString.concat(value);

Присоединяет value к строке (value может иметь любой численный тип данных). Возвращает true при успешном выполнении, false при ошибке. Аналог – сложение, myString + value;

myString.endsWith(myString2);

Проверяет, заканчивается ли myString символами из myString2. В случае совпадения возвращает true

myString.startsWith(myString2);

Проверяет, начинается ли myString символами из myString2. В случае совпадения возвращает true

myString.equals(myString2);

Возвращает true, если myString совпадает с myString2. Регистр букв важен

myString.equalsIgnoreCase (myString2);

Возвращает true, если myString совпадает с myString2. Регистр букв неважен

myString.indexOf(val);
myString.indexOf(val, from);

Ищет и возвращает номер (позицию) значения val в строке, ищет слева направо, возвращает номер первого символа в совпадении. val может быть char или String, то есть ищем в строке другую строку или символ. Можно искать, начиная с позиции from. В случае, когда не может найти val в строке, возвращает -1.

myString.lastIndexOf(val);
myString.lastIndexOf(val, from);

Ищет и возвращает номер (позицию) значения val в строке, ищет справа налево, возвращает номер последнего символа в совпадении. val может быть char или String, то есть ищем в строке другую строку или символ. Можно искать, начиная с позиции from. В случае, когда не может найти val в строке, возвращает -1.

myString.length();

Возвращает длину строки в количестве символов

myString.remove(index);
myString.remove(index, count);

Удаляет из строки символы, начиная с index и до конца, либо до указанного count

myString.replace(substring1, substring2);

В строке myString заменяет последовательность символов substring1 на substring2.

myString.reserve(size);

Зарезервировать в памяти количество байт size для работы со строкой

myString.c_str();

Преобразовывает строку в “СИ” формат (null-terminated string) и возвращает указатель на полученную строку

myString.trim();

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

myString.substring(from);
myString.substring(from, to);

Возвращает кусок строки, содержащейся в myString начиная с позиции from и до конца, либо до позиции to

myString.toCharArray(buf, len);

Раскидывает строку в массив – буфер buf (типа char []) с начала и до длины len

myString.getBytes(buf, len);

Копирует указанное количество символов len (вплоть до unsigned int) в буфер buf (byte [])

myString.toFloat();

Возвращает содержимое строки в тип данных float

myString.toDouble();

Возвращает содержимое строки в тип данных double

myString.toInt();

Возвращает содержимое строки в тип данных int

myString.toLowerCase();

Читайте также:  Автоматизация технологических процессов текст на английском

Переводит все символы в нижний регистр. Было ААААА – станет ааааа

myString.toUpperCase();

Переводит все символы в верхний регистр. Было ааааа – станет ААААА

Длина строки

Небольшой комментарий по поводу длины строки: мы можем узнать длину строки двумя способами, при помощи оператора sizeof() и метода length(). Давайте разберём отличия между ними:

Оператор sizeof вернёт размер строки в байтах. Строка содержит “нулевой символ” на конце, этот символ тоже весит один байт, соответственно оператор вернёт число 6. Метод length возвращает длину строки в количестве символов, не считая завершающий нулевой, поэтому результат будет 5.

F() macro

Строки являются очень тяжёлым с точки зрения использования памяти инструментом, ведь текст в строке хранится в оперативной памяти микроконтроллера, а её не так уж и много. Есть готовый инструмент, позволяющий удобно хранить текстовые данные во Flash памяти микроконтроллера. Этот способ хорош для вывода фиксированных текстовых данных, например, в монитор порта:

Строка “Hello, World!” будет записана во Flash память и не займёт 14 байт (13 + нулевой) в оперативной.

Массивы символов

Массивы символов, они же char array, являются ещё одним способом работы с текстовыми данными. Этот вариант имеет гораздо меньше возможностей по работе с текстом, но зато занимает меньше места в памяти (не используется элемент String) и работает значительно быстрее. К массиву символов применяются те же правила, какие работают для обычных массивов. Рассмотрим пример, в котором объявим массив символов, поработаем с ним, и выведем в порт:

В отличие от строк, массивы символов нельзя:

Длина строки char array

Для определения длины текста можно использовать оператор strlen, который возвращает количество символов в массиве. Сравним его работу с оператором sizeof:

Здесь оператор sizeof вернул количество байт, занимаемое массивом. Массив я специально объявил с размером бОльшим, чем содержащийся в нём текст. А вот оператор strlen посчитал и вернул количество символов, которые идут с начала массива и до нулевого символа в конце текста.

Массив строк

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

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

Экономия памяти

“Строки” в массиве строк тоже хранятся в оперативной памяти, что не очень здорово. Ещё больше не здорово то, что применить рассмотренный F() macro к ним нельзя, потому что фактически это не строки. То есть вот такой код приведёт к ошибке:

Как же быть? Массив строк можно сохранить в PROGMEM, программной памяти микроконтроллера, то есть во Flash. Вот такую конструкцию можно использовать как шаблон:

Да, сложно и громоздко, но при большом объёме текстовых данных это может спасти проект!

Arduino String – основная библиотека для работы со строками в ардуино. С ее помощью существенно упрощается использование массивов символов и строк в скетче. Объект типа String содержит множество полезных функций для создания и объединения строк, преобразований string to int (парсинг чисел) и int to string (форматирование чисел). Строки используются практически в любых проектах, поэтому и вероятность встретить String в скетче очень высока. В этой статье мы постараемся рассмотреть основные методы этого класса и наиболее часто возникающие ситуации.

Для чего нужен String в ардуино

Стандартным способом работы со строками в языке C является использование массива символов. Это все означало необходимость работы с указателями и понимания адресной арифметики. В ардуино и C++ у программистов появилось гораздо больше возможностей. Все “низкоуровневые” операции по работе со строкой выделены в отдельный класс, а для основных операций даже переопределены операторы. Например, для объединения срок мы просто используем хорошо знакомый знак “+”, а не зубодробильные функции типа malloc и strcpy. С помощью String мы работаем со строкой как с целым объектом, а не рассматриваем его как массив символов. Это позволяет сосредоточиться на логике скетча, а не деталях реализации хранения символов в памяти.

Естественно, у любого “упрощения” всегда есть свои подводные камни. String всегда использует больше оперативной памяти и в некоторых случаях функции класса могут медленнее обрабатываться. Поэтому в реальных больших проектах придется тщательно взвешивать все плюсы и минусы и не забывать, что никто не мешает нам работать со строками в стиле С. Все обычные функции обработки массивов char остаются в нашем арсенале и в arduino.

Создание строк в ардуино с помощью String

В ардуино у нас есть несколько способов создать строку, приведем основные:

  • char myCharStr [ ] = “Start”; – массив типа char с завершающим пустым символом;
  • String myStr = “Start”; – объявляем переменную, создаем экземпляр класса String и записываем в него константу-строку.
  • String myStr = String(“Start”); – аналогичен предыдущему: создаем строку из константы
  • String myStr(myCharStr); – создаем объект класса String с помощью конструктра, принимающего на вход массив типа char и создающего из char String.
  • String myStr = String(50); – создаем строку из целого числа (преобразование int to string).
  • String myStr = String(30, H); – создаем строку – представление числа в 16-чной системе (HEX to String)
  • String myStr = String(16, B); – создаем строку – представление числа в двоичной системе (Byte to String).

Каждый раз, когда мы объявляем в коде строку с использованием двойных кавычек, мы создаем неявный объект класса String, являющийся константой. При этом обязательно использование именно двойных кавычек: “String” – это строка. Одинарные кавычки нужны для обозначения отдельных символов. ‘S’ – это символ.

Функции и методы класса String

Для работы со строками в String предусмотрено множество полезных функций. Приведем краткое описание каждой из них:

  • String() – конструктор, создает элемент класса данных string. Возвращаемого значения нет. Есть множество вариантов, позволяющих создавать String из строк, символов, числе разных форматов.
  • charAt() возвращает указанный в строке элемент. Возвращаемое значение – n-ный символ строки.
  • compareTo() – функция нужна для проверки двух строк на равенство и позволяет выявить, какая из них идет раньше по алфавиту. Возвращаемые значения: отрицательное число, если строка 1 идет раньше строки 2 по алфавиту; 0 – при эквивалентности двух строк; положительное число, если вторая строка идет раньше первой в алфавитном порядке.
  • concat() – функция, которая объединяет две строки в одну. Итог сложения строк объединяется в новый объект String.
  • startsWith() – функция показывает, начинается ли строка с символа, указанного во второй строке. Возвращаемое значение: true, если строка начинается с символа из второй строки, в ином случае false.
  • endsWith() – работает так же, как и startsWith(), но проверяет уже окончание строки. Также возвращает значения true и false.
  • equals() – сравнивает две строки с учетом регистра, т.е. строки «start» и «START» не будут считаться эквивалентными. Возвращаемые значения: true при эквивалентности, false в ином случае.
  • equalsIgnoreCase() – похожа на equals, только эта функция не чувствительна к регистру символов.
  • getBytes() – позволяет скопировать символы указанной строки в буфер.
  • indexOf() – выполняет поиск символа в строке с начала. Возвращает значение индекса подстроки val или -1, если подстрока не обнаружена.
  • lastIndexOf() –выполняет поиск символа в строке с конца.
  • length() – указывает длину строки в символах без учета завершающего нулевого символа.
  • replace() – заменяет в строке вхождения определенного символа на другой.
  • setCharAt() – изменяет нужный символ в строке.
  • substring() – возвращает подстроку. Может принимать два значения – начальный и конечный индексы. Первый является включительным, т.е. соответствующий ему элемент будет включаться в строку, второй – не является им.
  • toCharArray() – копирует элементы строки в буфер.
  • toLowerCase() – возвращает строку, которая записана в нижнем регистре.
  • toUpperCase() – возвращает записанную в верхнем регистре строку.
  • toInt() – позволяет преобразовать строку в число (целое). При наличии в строке не целочисленных значений функция прерывает преобразование.
  • trim() – отбрасывает ненужные пробелы в начале и в конце строки.
Читайте также:  Декоративная штукатурка для внутренней отделки стен шелковая

Объединение строк Arduino

Объединить две строки в одну можно различными способами. Эта операция также называется конкатенацией. В ее результате получается новый объект String, состоящий из двух соединенных строк. Добавить к строке можно различные символы:

  • String3 = string1 + 111; // позволяет прибавить к строке числовую константу. Число должно быть целым.
  • String3 = string1 + 111111111; // добавляет к строке длинное целое число
  • String3 = string1 + ‘А’; // добавляет символ к строке
  • String3 = string1 + “aaa”;// добавляет строковую постоянную.
  • String3 = string1 + string2; // объединяет две строки вместе.

Важно осторожно объединять две строки из разных типов данных, так как это может привести к ошибке или неправильному результату.

Arduino string to int и string to float

Для конвертации целочисленных значений string to int используется функция toInt().

String MyStr = “111”;

int x = MyStr.toInt();

Если нужно конвертировать объект с плавающей запятой, применяется функция atof().

String MyStr = “11.111”;

MyStr.toCharArray(myStr1, MyStr.length()); // копируется String в массив myStr1

float x = atof(myStr1); // преобразование в float

Преобразование int to string

Для создания строки из числа не требуется делать особых телодвижений. Мы можем просто объединить строку и число:

String str = “Строка номер “+ i;

Можем создать объект, используя конструктор

String str = String(50);

Можем объединить оба способа:

String str = “Строка номер “+ String(50);

Преобразование String в массив char

Тип данных Char позволяет объявлять текстовые строки несколькими способами:

  • char myStr1[10]; – в данном случае объявлен массив определенного размера.
  • char myStr2 [6] = <‘a’, b, ‘c’, ‘d’, ‘e’>; – объявлен сам массив. Конечный символ не записанявно, его прибавит сам компилятор.
  • char myStr3[6] = <‘a’, b, ‘c’, ‘d’, ‘e’’/0’>; – объявлен массив, при этом в конце прописан признак окончания строки.
  • char myStr4 [ ] = “abcde”; – инициализация массива строковой постоянной. Размер и завершающий символ добавляются автоматически компилятором.
  • char myStr5 [6 ] = “abcde”; – инициализация массива с точным указанием его размера.
  • char myStr 6[30 ] = “abcde”; – аналогично, но размер указан больше для возможности использования строк большей длины.

Еще раз напомним, что в типе данных char строковые константы нужно записывать в двойные кавычки «Abcde», а одиночные символы – в одинарные ‘a’.

Конвертировать строку в массив сhar array можно при помощи следующего кода:

String stringVar = “111”;

Можно сделать обратное преобразование – char to string.

char[] chArray = “start”;

Пример преобразования String to const char*. Указание звездочкой char*означает, что это массив указателей.

String stringVar=string (`start);

Char charVar[ sizeof [stringVar)];

Заключение о String и ардуино

В этой статье мы рассмотрели основные вопросы использования String для работы со строками arduino. Как показывают примеры, ничего страшного и сложного в этом классе нет. Более того, зачастую мы можем даже не догадываться, что работаем с классом String: мы просто создаем переменную нужного типа, присваиваем ей строку в двойных кавычках. Создав строку, мы используем все возможности библиотеки String: можем без проблем модифицировать строку, объединять строки, преобразовывать string в int и обратно, а также делать множество других операций с помощью методов класса.

В ситуациях, когда скетч большой и перед нами встает дефицит памяти, использовать String нужно осторожно, по возможности заменяя на char*. Впрочем, в большинстве первых проектов начинающего ардуинщика таких ситуаций не много, поэтому рекомендуем использовать String без опаски – это предотвратит появление ошибок адресной арифметики, возникающих при работе с массивами char.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *