Стандартные строковые функции и сообщения
Цель лекции
Расширение возможностей обработки строк с помощью стандартных функций, вывод сообщений в окнах различного типа, получение от пользователя данных с помощью функции-запроса.
Функции для работы со строками
В "Символы и строки" мы достаточно подробно познакомились со строковыми и символьными типами данных, изучили три компонента, с помощью которых пользователь может вводить в программу строки. Однако этих инструментов зачастую бывает недостаточно для обработки строк. В практике программирования над строками то и дело приходится совершать какие-то действия: сравнивать строки между собой, преобразовывать строку в строчные или в прописные буквы, находить часть строки и т.п. Сегодня мы разберем наиболее востребованные строковые функции.
А для того, чтобы посмотреть работу функций на практике, создадим новое приложение. Это будет простое приложение с единственной кнопкой посреди окна. Сохраните проект в папку 06-01, поскольку проект будет совсем простой, имена модуля и проекта можно оставить без изменений. Сгенерируйте событие нажатия на кнопку, в этом событии мы и будем экспериментировать над строками.
Объединение (конкатенация) строк
Программисту довольно часто приходится в коде объединять несколько строк в одну. Мы уже делали подобное объединение в прошлых лекциях. Для объединения служит оператор "+":
string_1 + string_2 + …string_n;
В качестве строки можно использовать и отдельные символы, например, символ перехода на другую строку. Напишем следующий код:
procedure TForm1.Button1Click(Sender: TObject); var s1: String; begin s1:= 'Строка №1' + #13 + 'Строка №2' + #13 + 'Строка №3'; ShowMessage(s1); end;
Здесь, в переменной s1 мы собрали строку из 5 кусочков, причем два из них - символы перехода на новую строку. Сохраните проект, скомпилируйте его и убедитесь, что полученное сообщение будет трехстрочным.
Функция Concat() делает то же самое - объединяет строки. Её синтаксис такой (в квадратные скобки принято помещать необязательные параметры функций):
Concat(S1 [, S2,…Sn]); Здесь S1, S2 и т.д. - строки. Предыдущий пример можно было бы записать и так: s1:= Concat('Строка №1', #13, 'Строка №2', #13, 'Строка №3');
Длина строки
Поскольку мы предоставляем пользователям возможность вводить различные строки, нередко возникает необходимость выяснить длину этих самых строк. Для этого существует функция Length(). Её синтаксис:
Length(S);
где S - строка. Функция возвращает нам размер количество символов в этой строке. Однако в Lazarus не все так просто. Давайте изменим предыдущий код обработчика кнопки на следующий:
procedure TForm1.Button1Click(Sender: TObject); var s1: String; begin s1:= 'Hello'; ShowMessage(IntToStr(Length(s1))); end;
Поскольку результатом работы функции Length() будет целое число - количество символов, то для вывода этих данных на экран нам приходится преобразовать полученное число в строковый тип, что мы и делаем в коде
ShowMessage(IntToStr(Length(s1)));
Подобные преобразования мы будем изучать позже, пока лишь нужно понять вот что: данная строка кода реализует сложное для начинающих программистов выражение, которое выполняется компьютером в три этапа:
- Length() - вычисление размера строки s1.
- IntToStr() - преобразование полученного в №1 результата из целого числа в строку.
- ShowMessage() - вывод преобразованного в №2 результата на экран.
Если вы откомпилируете проект и запустите его на выполнение, то получите результат: 5. Столько символов в строке "Hello". Однако измените эту строку на "Привет" и снова выполните программу:
s1:= 'Привет'; ShowMessage(IntToStr(Length(s1)));
Мы ожидаем получить число 6 - количество символов в слове "Привет", но неожиданно получаем 12! Дело в том, что функция работает с ANSI-строками, то есть с теми, что занимают по 1 байту на символ. А кириллица - это не ANSI а UTF8, и требует по 2 байта на символ! Как быть? В подобных случаях используйте UTF8-аналоги строковых функций. То есть, вместо Length() используйте UTF8Length(). Эта функция гарантированно вернет количество символов в строке, на каком бы языке эти символы не вводились. Но для использования UTF8Length() нужно подключить модуль LCLProc, где и реализованы все UTF8-функции.
Пролистайте код выше, на начало модуля, и добавьте LCLProc в раздел uses:
Теперь мы можем изменить наш обработчик:
procedure TForm1.Button1Click(Sender: TObject); var s1: String; begin s1:= 'Привет'; ShowMessage(IntToStr(UTF8Length(s1))); end;
Вот теперь мы получим в результате число 6.
Таким образом, если вы точно знаете, что будете иметь дело только с английскими символами, то для определения количества символов в строке, и занимаемых этой строкой байт, используйте функцию Length(). Во всех остальных случаях Length() можно использовать для получения размера строки в байтах, а UTF8Length() - для получения количества символов в строке.
Поиск в строке
Иногда необходимо выяснить, есть ли в строке нужный текст. Для этого служат функции
- Pos() - для ANSI-символов
- UTF8Pos() - для кириллицы (UTF8-символы) - требует подключения модуля LCLProc
Pos(Substr, Str); UTF8Pos(Substr, Str);
Здесь Substr - искомый текст; Str - строка, в которой ищется текст. Функции возвращают в качестве результата целое число. Если искомый текст в строке отсутствует, обе функции вернут ноль. Иначе - номер символа строки, с которого начинается найденная подстрока. Переделаем код обработчика кнопки (модуль LCLProc у нас уже подключен):
procedure TForm1.Button1Click(Sender: TObject); var s1: String; begin s1:= 'Привет'; ShowMessage(IntToStr(UTF8Pos('ив', s1))); //результат: 3 end;
Запустив программу на выполнение, убедимся, что функция
UTF8Pos('ив', s1)
возвращает результат 3 - номер первого символа искомой подстроки в строке "Привет".
Если в строке содержится несколько искомых подстрок, функции вернут номер первого такого вхождения. А если для строки с русскими буквами использовать функцию Pos() вместо UTF8Pos(), результат будет неверный.
Получение подстроки
Чтобы из строки получить ее часть (подстроку), применяют функции
- Copy() - для ANSI-символов
- UTF8Copy() - для кириллицы - требует подключения модуля LCLProc
Copy(Str, StartCharIndex, Count); UTF8Copy(Str, StartCharIndex, Count);
Здесь Str - строка исходного текста; StartCharIndex - номер первого символа подстроки; Count - количество символов подстроки. Снова переделаем обработчик кнопки:
procedure TForm1.Button1Click(Sender: TObject); var s1: String; begin s1:= 'Привет'; ShowMessage(UTF8Copy(s1, 3, 2)); end;
В результате выполнения программы вы убедитесь, что
UTF8Copy(s1, 3, 2)
из строки "Привет" вернет "ив" - подстроку, начиная с третьего символа, размером два символа.
Если для кириллицы вместо UTF8Copy() использовать Copy(), результат будет неверным.
Удаление части строки
Для удаления части строки применяют функции Delete() и UTF8Delete().
Delete(Str, StartCharIndex, Count); UTF8Delete(Str, StartCharIndex, Count);
Здесь Str - строка исходного текста; StartCharIndex - номер первого символа удаляемой подстроки; Count - количество удаляемых символов. Эта функция отличается от других тем, что она изменяет исходную строку Str, обрезает ее. Другие функции оставляли эту строку без изменений. Итак, наш новый код:
procedure TForm1.Button1Click(Sender: TObject); var s1: String; begin s1:= 'Привет'; UTF8Delete(s1, 3, 2); //обрезаем строку ShowMessage(s1); end;
Функцией UTF8Delete(s1, 3, 2) мы ампутировали строку s1, вырезали из нее, начиная с третьего символа, подстроку размером 2 символа. В результате у нас осталась строка "Прет". Как и с предыдущими функциями, применение с кириллицей не UTF8-варианта исказит результат.