Лекция №7. String
Как в обычной жизни, одиночные символы соединяются в слова и строки - это текст, заключённый в двойные кавычки: "Hello, World!". У нас есть два набора инструментов для работы с ними:
Статические строки - они же массивы символов char, являются стандартными для языка C/C++ и работают одинаково на любой платформе. О них поговорим в следующем уроке.
Динамические String-строки, в Arduino за них отвечает отдельная библиотека, которая входит в состав "ядра". Эти строки просты и удобны в использовании, поэтому сначала разберём работу с ними.
Базовый синтаксис
Строка создаётся как обычная переменная:
String s;
При создании также можно присвоить строке значение. String позволяет автоматически преобразовывать любой стандартный тип данных в строку:
String s1 = 12345; // из целого числа
String s2 = 3.14; // из float
String s3 = "text"; // из строковой константы
String s4 = F("text");// из строковой константы с F
String s5 = 's'; // из символа
int val = 1234;
String s6 = val; // из переменной
String s7 = s6; // из другой строки
Помимо такой инициализации, есть ещё вариант с конструктором, он более гибкий: в скобках можно указать значение, а для некоторых типов данных доступны дополнительные настройки:
String s1(1234); // из целого числа, в десятичном виде
String s2(1234, BIN); // с указанием разрядности (BIN, DEC, HEX)
String s3(3,14, 1); // из float, с указанием кол-ва знаков после запятой
String s4("text"); // из строковой константы
String s5(F("text")); // из строковой константы с F
String s6(s4); // из другой строки
Более того, данный способ работает быстрее присваивания, так как выделяет память под строку один раз. В варианте с присваиванием сначала выделяется пустая строка, а затем увеличивается под новые данные.
Сложение String
К строке можно прибавить любой тип данных, так же как при создании, по одному действию в строке кода:
String s;
s += 12345; // из целого числа
s += 3.14; // из float
s += "text"; // из строковой константы
s += F("text");// из строковой константы с F
s += 's'; // из символа
int val = 1234;
s += val; // из переменной
String s2(1234);
s += s2; // из другой строки
Также String позволяет складывать строки между собой при помощи оператора +. В тексте ниже данные имеют любой тип, с которым String поддерживает сложение (см. выше):
Одним из слагаемых должна быть строка, как выше: стринг + данные или данные + стринг
Операция сложения возвращает строку обратно, что позволяет сделать "каскад" из таких сложений и собрать строку "одной строкой кода", сборка происходит слева направо: стринг + данные1 + данные2 или данные1 + стринг + данные2 + данные3
Результат всей суммы можно:
Приравнять к String: стринг = стринг + данные1 + данные2
Отправить в функцию, которая принимает String: f(стринг + данные1 + данные2)
И так далее
String s;
s = String("Hello") + ',' + "World" + 1234 + 3.14;
Serial.println(s + "text" + 1234);
Для сборки строки данный вариант менее предпочтительный, чем предыдущий с +=. Ниже разберёмся, почему.
Доступ к символам
К строке можно обратиться как к массиву и прочитать или изменить символ по порядку:
String s("hello!");
s[0] = 'H';
// Здесь s == Hello!
char c = s[1];
// здесь c == e
Сравнение String
Строки можно сравнивать между собой и с обычными строками (const char*):
String s1 = "text1";
String s2 = "text2";
if (s1 == s2); // false
if (s1 == "text1"); // true
if (s2 != "text2"); // false
Остальные методы
Рассмотрим все библиотечные методы для работы со строками, они применяются к строке через точку. В рассмотренных ниже примерах "тестовая" строка называется myString. Также оставлю некоторые комментарии по оптимизации.
charAt()
myString.charAt(index) - возвращает элемент строки myString под номером index. Аналог - myString[index]; - лучше использовать его вместо charAt()!
setCharAt()
myString.setCharAt(index, val) - записывает в строку myString символ val на позицию index. Аналог - myString[index] = val; - лучше использовать его вместо setCharAt()!
compareTo()
myString.compareTo(myString2)
Возвращает отрицательное число, если myString идёт до myString2
Возвращает положительное число, если myString идёт после myString2
Возвращает 0, если строки одинаковы
concat()
myString.concat(value) - присоединяет value к строке (value может иметь любой численный тип данных). Возвращает true при успешном выполнении, false при ошибке. Аналог - сложение, myString + value;
endsWith()
myString.endsWith(myString2) - проверяет, заканчивается ли myString строкой myString2. В случае совпадения возвращает true
startsWith()
myString.startsWith(myString2) - проверяет, начинается ли myString строкой myString2. В случае совпадения возвращает true
equals()
myString.equals(myString2) - возвращает true, если myString совпадает с myString2. Регистр букв важен
equalsIgnoreCase()
myString.equalsIgnoreCase(myString2) - возвращает true, если myString совпадает с myString2. Регистр букв неважен
indexOf()
myString.indexOf(val) и myString.indexOf(val, from) - ищет и возвращает номер (индекс) значения val в строке. Ищет слева направо, возвращает номер первого символа в совпадении. val может быть char или String, то есть ищем в строке другую строку или символ. Можно искать, начиная с позиции from. В случае, когда не может найти val в строке, возвращает -1.
lastIndexOf()
myString.lastIndexOf(val) и myString.lastIndexOf(val, from) - ищет и возвращает номер (индекс) значения val в строке. Ищет справа налево, возвращает номер последнего символа в совпадении. val может быть char или String, то есть ищем в строке другую строку или символ. Можно искать, начиная с позиции from. В случае, когда не может найти val в строке, возвращает -1.
length()
myString.length() - возвращает длину строки в количестве символов
remove()
myString.remove(index) и myString.remove(index, count) - удаляет из строки символы, начиная с index и до конца, либо до указанного count
replace()
myString.replace(substring1, substring2) - в строке myString заменяет последовательность символов substring1 на substring2.
String myString = "lol kek 4eburek";
// заменить чебурек на пельмень
myString.replace("4eburek", "pelmen");
reserve()
myString.reserve(size) - зарезервировать в памяти количество байт size для работы со строкой
c_str()
myString.c_str() - возвращает указатель char* на строку
trim()
myString.trim() - удаляет пробелы из начала и конца строки. Действует со строкой, к которой применяется
substring()
myString.substring(from) и myString.substring(from, to) - возвращает подстроку, содержащуюся в myString с позиции from и до конца, либо до позиции to
String myString = "lol kek 4eburek";
String chebur = myString.substring(8);
// строка chebur содержит в себе "4eburek"
toCharArray()
myString.toCharArray(buf, len) - записывает строку в массив - буфер buf (типа char []) с начала и до длины len. Автоматически добавляет символ конца строки. В большинстве случаев лучше воспользоваться вариантом c_str()
getBytes()
myString.getBytes(buf, len) - копирует указанное количество символов len в буфер buf (byte []). Автоматически добавляет символ конца строки.
toFloat()
myString.toFloat() - конвертирует и возвращает содержимое строки в тип данных float
toDouble()
myString.toDouble() - конвертирует и возвращает содержимое строки в тип данных double
toInt()
myString.toInt() - конвертирует и возвращает содержимое строки в тип данных int
String myString = "10500";
int val = myString.toInt();
// val теперь 10500
toLowerCase()
myString.toLowerCase() - переводит все символы в нижний регистр. Было ААААА - станет ааааа
toUpperCase()
myString.toUpperCase() - переводит все символы в верхний регистр. Было ааааа - станет ААААА