Шрифты и строки
Строки в Juce
Подобно многим другим GUI toolkit'ам в Juce представление строковых данных реализовано как класс (String). Мы уже встречались с этим классом в вышеприведённых программах.
Класс String имеет несколько конструкторов:
- String() throw() — создаёт пустую строку;
- String(const String& other) throw() — создаёт строку из другого объекта того же класса String;
- String(const char* text) — создаёт строку из массива символов, оканчивающегося нулём;
- String(const char* text, size_t maxChars) — создаёт строку из массива символов определённой длины;
- String(const juce_wchar* unicodeText) — создаёт строку из массива символов в формате Юникод, оканчивающегося нулём; typedef wchar_t juce_wchar — платформонезависимый тип символа Юникод;
- String(const juce_wchar* unicodeText, size_t maxChars) — создаёт строку из массива символов в формате Юникод определённой длины.
Класс String предоставляет целую серию методов и операторов, позволяющих проводить со строками разного рода операции: соединять их, осуществлять поиск подстрок и т.п.
Для класса String имеется два перегруженных оператора: присваивания (=) и конкатенации (+=).
Оператор = замещает содержимое объекта класса String содержимым другой строки.
Оператор += осуществляет объединение или конкатенацию строк. При этом в конец исходной строки могут быть добавлены данные следующих типов:
- символ (char);
- символ Юникод (juce_wchar);
- массив символов Юникод (juce_wchar*);
- строка (String);
- целое число (int);
- беззнаковое целое (unsigned int).
Объединение строк можно осуществить также с помощью функции-члена класса String void String::append(const juce_wchar* textToAppend, int maxCharsToTake), где textToAppend — строка, добавляемая в конец исходной, а maxCharsToTake — максимальное число передаваемых символов.
Строки можно сравнивать между собой с помощью набора методов класса:
- bool String::equalsIgnoreCase(const String& other) const throw() — сравнение с другой строкой без учёта регистра;
- bool String::equalsIgnoreCase(const juce_wchar* other) const throw() — сравнение с другой строкой (представленной массивом символов Юникод) без учёта регистра;
- bool String::equalsIgnoreCase(const char* other) const throw() — сравнение с другой строкой (представленной массивом символов) без учёта регистра;
- int String::compare(const String& other) const throw() — сравнение с другой строкой с учётом регистра;
- int String::compare(const char* other) const throw() — сравнение с другой строкой (представленной массивом символов) с учётом регистра;
- int String::compare(const juce_wchar* other) const throw() — сравнение с другой строкой (представленной массивом символов Юникод) с учётом регистра;
- int String::compareIgnoreCase(const String& other) const throw() — сравнение с другой строкой без учёта регистра;
- int String::compareLexicographically(const String& other) const throw() — лексикографическое сравнение с другой строкой.
- Узнать, является ли строка пустой, можно с помощью следующих методов:
- bool String::isEmpty() const throw() — возвращает true, если строка не содержит ни одного символа;
- bool String::isNotEmpty() const throw() — возвращает true, если строка содержит хотя бы один символ.
Того же результата можно добиться, проверив длину строки в символах методом int String::length() const throw().
Следует помнить, что строка, содержащая пробелы, пустой не является, поэтому функция isEmpty, вызываемая ею, будет возвращать false. Как правило, пользователь воспринимает текстовое поле, в котором нет других символов, кроме пробелов, именно как пустое. Библиотека Juce включает удобную функцию bool String::containsNonWhitespaceChars() const throw(), которая возвращает true, если вызывающая строка содержит какие-либо символы, помимо пробелов.
Поиск строк и символов в тексте — одна из наиболее часто возникающих задач при разработке приложений. Класс String содержит довольно много методов для её решения.
Прежде всего, это методы поиска подстроки:
- const String String::substring(int startIndex) const — возвращает часть вызывающей строки от символа startIndex и до её конца;
- const String String::substring(int startIndex, int endIndex) const — возвращает часть вызывающей строки между символами startIndex и endIndex.
Для того, чтобы узнать, содержит ли строка подстроку или символы (в любой позиции), используются следующие функции:
- bool String::contains(const String& text) const throw() — проверяет, содержит ли строка подстроку text. Чувствительна к регистру. Если в качестве параметра была передана пустая строка, функция всё равно возвращает true.
- bool String::containsIgnoreCase(const String& text) const throw() — работает аналогично предыдущей функции, но не учитывает регистр символов.
- bool String::containsChar(juce_wchar character) const throw() — проверяет, содержит ли строка символ, переданный в качестве параметра.
- bool String::containsAnyOf(const String& charactersItMightContain) const throw() — возвращает true, если в вызывающей строке есть какие-либо символы из набора, принимаемого в качестве параметра.
- bool String::containsOnly(const String& charactersItMightContain) const throw() — возвращает false, если в вызывающей строке отсутствует какой-либо из символов набора, принимаемого в качестве параметра.
- bool String::containsWholeWord(const String& wordToLookFor) const throw() — возвращает true, если вызывающая метод строка содержит слово wordToLookFor, окружённое символами, не являющимися буквами и цифрами.
Для замены определённой части строки другой класс String предоставляет метод const String String::replace(const String& stringToReplace, const String& stringToInsertInstead, bool ignoreCase = false) const, все вхождения подстроки stringToReplace строкой stringToInsertInstead с учётом или без учёта регистра в зависимости от принимаемого значения параметра ignoreCase.
Для замены одного символа в строке можно воспользоваться функцией const String String::replaceCharacter(juce_wchar characterToReplace, juce_wchar characterToInsertInstead) const. Кроме того, класс String включает метод, который позволяет заменить один набор символов другим: const String String::replaceCharacters(const String& charactersToReplace, const String& charactersToInsertInstead) const. Он возвращает строку, в которой каждый символ из первого набора (charactersToReplace) замещается соответствующим символом из второго набора (charactersToInsertInstead) в эквивалентной позиции. Понятно, что передаваемые в функцию две строки должны быть одинакового размера. Например, при вызове replaceCharacters("abc", "def") в результирующей строке "a" замещается на "d", "b"на "e" и т.п.
Близким к предыдущей функции является метод класса String const String String::retainCharacters(const String& charactersToRetain) const, который возвращает строку, сохраняющую только тот набор символов, содержавшихся в вызвавшей строке, который был передан в качестве параметра. Например, если объект класса String, содержащий строку "1122334455", обратится к методу retainCharacters("432"), то будет возвращена строка "223344".
Для преобразования данных строки в верхний или нижний регистр используются методы const String String::toLowerCase() const и const String String::toUpperCase() const, которые возвращают, соответственно, вариант вызвавшей строки в нижнем и верхнем регистре.
Достаточно часто встречается ситуация, когда необходимо конвертировать числовые значения в строковые и наоборот. В первом случае необходимо создать объект класса String, в качестве параметра конструктора которого передать конвертируемое число. Принимаемыми в качестве параметра конструктора типами могут быть short int, unsigned short int, int, unsigned int, int64, uint64, float и double. Например:
String sNumber(1234); // Строка содержит текст "1234".
Преобразование из строкового в числовое значение производится методами, содержащими в своём имени название типа:
- int String::getIntValue() const throw();
- int64 String::getLargeIntValue() const throw();
- float String::getFloatValue() const throw();
- double String::getDoubleValue() const throw();
- int String::getHexValue32() const throw();
- int64 String::getHexValue64() const throw();
Последние две функции возвращают шестнадцатеричное число соответствующего размера; прочие символы, если их содержит строка, игнорируются. Пример использования функции getFloatValue приведён в листинге 6.4 .
Кроме того, класс String включает довольно интересный метод int String::getTrailingIntValue() const throw(), который возвращает целое число, находящееся в конце строки. Например:
String sNumber("321 xyz654"); // Функция возвращает 654 int iNumber = sNumber.getTrailingIntValue()