Расширение возможностей обработки строк с помощью стандартных функций, вывод сообщений в окнах различного типа, получение от пользователя данных с помощью функции-запроса.
В прошлой лекции мы достаточно подробно познакомились со строковыми и символьными типами данных, изучили три компонента, с помощью которых пользователь может вводить в программу строки. Однако этих инструментов зачастую бывает недостаточно для обработки строк. В практике программирования над строками то и дело приходится совершать какие-то действия: сравнивать строки между собой, преобразовывать строку в строчные или в прописные буквы, находить часть строки и т.п. Сегодня мы разберем наиболее востребованные строковые функции.
А для того, чтобы посмотреть работу функций на практике, создадим новое приложение. Это будет простое приложение с единственной кнопкой посреди окна. Сохраните проект в папку 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:
(рис 6.1) Добавление модуля в раздел 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-варианта исказит результат.
Иногда требуется сравнить две строки, или найти какую-то подстроку. Но не всегда известно, в каком регистре пользователь ввел текст. К примеру, нам нужно узнать, ввел ли пользователь слово "Москва", или что-то другое. Пользователь знает, что он должен ввести название нашей столицы, однако он может полениться нажать <Shift>, и в результате введет "москва". Или нажмет <Caps Lock> и введет "МОСКВА". А поскольку слово он написал без ошибок, то уверен, что все сделал правильно. Но мы-то ожидаем не просто слово, а слово со строго определенным описанием! К сожалению, пользователи далеко не всегда вводят то, что нужно, и программистам приходится идти на всевозможные хитрости, чтобы добиваться нужного результата. Например, мы можем заранее преобразовать введенное пользователем слово в верхний регистр (то есть, сделать все буквы заглавными), и сравнить его со словом "МОСКВА". И какие бы буквы пользователь первоначально не вводил, результат все равно будет верным.
Точно также, мы можем все буквы сделать строчными, и сверить строку с текстом "москва". Для подобных преобразований служат следующие функции:
UpperCase(Str) |
- Преобразует ANSI-строку Str в верхний регистр |
UTF8UpperCase(Str) |
- Преобразует UTF8-строку Str в верхний регистр |
LowerCase(Str) |
- Преобразует ANSI-строку Str в нижний регистр |
UTF8LowerCase(Str) |
- Преобразует UTF8-строку Str в нижний регистр |
Изменим код обработчика:
procedure TForm1.Button1Click(Sender: TObject);
var
s1: String;
begin
s1:= 'Москва';
ShowMessage(UTF8UpperCase(s1));
ShowMessage(UTF8LowerCase(s1));
end;
Сохраните проект и запустите его на выполнение. Мы получим два сообщения: заглавными и строчными буквами.
Нам то и дело требуется выводить пользователю различные сообщения. И в этой лекции, и в предыдущих лекциях, мы уже неоднократно пользовались одной такой функцией - ShowMessage(). Её синтаксис очень простой:
ShowMessage('Текст сообщения');
В результате будет выведено окно с сообщением, которое не даст пользователю продолжать работу, пока он не нажмет кнопку "ОК":
(рис 6.2) Сообщение ShowMessage()
Еще один вариант сообщения - функция Application.MessageBox(). Данная Windows API-функция позволяет вывести сообщение с разными настройками. Синтаксис функции следующий:
Application.MessageBox(Text: PChar; Caption: PChar; Flags: LongInt): Integer;
В качестве аргументов мы должны указать текст сообщения Text, заголовок окна с сообщением Caption и флаги - значок сообщения и используемые кнопки. И Text, и Caption имеют тип PChar. Флаги имеют целочисленный тип, однако нам нужно запомнить только символьные обозначения этих флагов:
| Значки сообщения | |
|---|---|
MB_ICONERROR |
Белый крестик в красном круге. Такой значок обычно используют в сообщениях об ошибке. |
MB_ICONHAND |
|
MB_ICONSTOP |
|
|
Синий знак вопроса в белой выноске. Таким способом помечают вопрос, обращенный к пользователю. |
MB_ICONWARNING |
Черный восклицательный знак в желтом треугольнике. Таким знаком привлекают внимание пользователя к вероятной опасности, которая может последовать в результате действий пользователя. |
MB_ICONEXCLAMATION |
|
MB_ICONINFORMATION |
Синяя буква "i" в белой выноске. Таким способом помечают какую-то информацию для пользователя. |
MB_ICONASTERISK |
|
| Кнопки сообщения | |
MB_OK |
Кнопка "OK" в середине окна. |
MB_OKCANCEL |
Кнопки "OK" и "Cancel". |
MB_ABORTRETRYIGNORE |
Кнопки "Abort", "Retry" и "Ignore". |
MB_YESNOCANCEL |
Кнопки "Yes", "No" и "Cancel". |
MB_YESNO |
Кнопки "Yes" и "No". |
MB_RETRYCANCEL |
Кнопки "Retry" и "Cancel". |
Примечание: Чтобы пользоваться функцией Application.MessageBox(), нужно в разделе uses подключить модуль LCLType.
Как видно из таблицы, некоторые значки сообщений совпадают. Указывать нужно какое-то одно из них. Переделаем код обработчика кнопки:
procedure TForm1.Button1Click(Sender: TObject);
begin
Application.MessageBox('Сообщение', 'Заголовок',
MB_ICONINFORMATION + MB_ABORTRETRYIGNORE);
end;
В результате получим такое окно сообщения:
(рис 6.3) Сообщение Application.MessageBox()
Вы заметили, что в качестве флага используется сумма значка и кнопок? И то, и другое, на самом деле, целое число. Но нам удобней запомнить эти значения в символьном варианте.
А как мы узнаем, какую кнопку нажал пользователь? Эта функция возвращает значение - кнопку, нажатую пользователем, которая может быть:
IDOKIDCANCELIDABORTIDRETRYIDIGNOREIDYESIDNOIDCLOSEIDHELPТо есть, если пользователь нажал кнопку "Abort", функция вернет значение IDABORT. А раз так, мы можем делать проверку на нажатую кнопку. Снова изменим код обработчика:
procedure TForm1.Button1Click(Sender: TObject);
begin
if Application.MessageBox('Сообщение', 'Заголовок', MB_ICONQUESTION +
MB_YESNOCANCEL) = IDYES then ShowMessage('Вы нажали кнопку Yes');
end;
Логическую конструкцию if мы будем изучать в следующей лекции, здесь лишь заметим, что сообщение ShowMessage() будет выведено только в том случае, если пользователь нажал кнопку "Yes". Во всех остальных случаях это сообщение не выйдет.
Похожим образом действует Windows API-функция MessageDlg(), которая описана в модуле Dialogs. Этот модуль включается в раздел uses автоматически, поэтому нам не нужно даже что-то туда добавлять. Синтаксис этой функции несколько отличается от предыдущей:
MessageDlg(Caption, Text, MessageType, MessageButton, HelpKeyword): Integer;
Здесь Caption и Text соответственно, текст заголовка и самого сообщения, тип PChar. Далее идет тип сообщения MessageType, - значок сообщения, который может быть:
mtWarning |
- Восклицательный знак, подобен MB_ICONWARNING функции Application.MessageBox() |
mtError |
- крестик |
mtInformation |
- буква "i" |
mtConfirmation |
- вопросительный знак |
mtCustom |
- пользовательское окно без значка. |
Далее следует тип кнопок MessageButton, который может быть:
mbYes |
mbNo |
mbOK |
mbCancel |
mbAbort |
mbRetry |
mbIgnore |
mbAll |
mbNoToAll |
mbYesToAll |
mbHelp |
mbClose |
Названия кнопок говорят сами за себя, комментарии тут излишни. Кнопки указывают в квадратных скобках, отделяя друг от друга запятыми, например: [mbYes, mbNo, mbIgnore].
Последний параметр HelpKeyword определяет экран контекстной справки, которая будет появляться, если пользователь нажмет <F1>. Обычно в этом параметре указывают значение 0 - нет справки.
Функция MessageDlg() возвращает значение - нажатую кнопку, которая соответствует типу кнопок, указанному выше. Возвращаемое значение вместо "mb" начинается на "mr", то есть, если пользователь нажал кнопку "Yes" (тип mbYes), то будет возвращено значение mrYes.
Снова изменим код:
procedure TForm1.Button1Click(Sender: TObject);
begin
if MessageDlg('Подтверждение', 'Вы действительно хотите закрыть программу?',
mtConfirmation, [mbYes, mbNo, mbIgnore], 0) = mrYes then Close;
end;
В данном случае пользователю выводится запрос на подтверждение закрытия программы, и если он нажимает кнопку "Yes", программа закрывается (выполняется оператор Close). Так как функции MessageDlg() и Application.MessageBox() похожи, выбирайте любую, на свой вкус.
Иногда требуется получить от пользователя какие-то данные (вспомните программу Hello из второй лекции). В этом случае можно использовать компонент TEdit, но можно поступить проще - воспользоваться функцией InputQuery().
Функция InputQuery() выводит окно запроса. Синтаксис функции такой:
InputQuery(Caption, Message, StrVar);
Здесь, Caption и Message - соответственно, текст заголовка и текст сообщения внутри окна. StrVar - переменная строкового типа, которая должна быть объявлена заранее. Если в этой переменной есть текст, он выводится в строке редактирования как текст по умолчанию. Если переменная пуста, то пуста будет и строка. Если пользователь что-то введет в строку и нажмет кнопку "ОК", этот текст запишется в переменную StrVar, а функция вернет значение True (Истина). В противном случае функция вернет значение False (Ложь). Переделаем код обработчика:
procedure TForm1.Button1Click(Sender: TObject);
var
YourName: String;
begin
YourName:= 'Неизвестный';
if InputQuery('Кто вы?', 'Укажите ваше имя', YourName) then
ShowMessage('Привет, ' + YourName + '!');
end;
Напомню, что с логической конструкцией if мы познакомимся в следующей лекции, а пока разберем код. Вначале мы присваиваем строковой переменной YourName текст "Неизвестный". Затем мы вызываем функцию InputQuery(). Мы указываем заголовок окна "Кто вы?", текст сообщения "Укажите ваше имя" и текстовую переменную YourName. Текст, который мы ранее поместили в эту переменную, будет выходить в строке редактирования:
(рис 6.4) Результат работы функции InputQuery()
Если пользователь введет какой-то другой текст, он попадет в переменную YourName, функция вернет True и в результате будет выведено сообщение с приветствием
ShowMessage('Привет, ' + YourName + '!');
Функция InputQuery() часто бывает полезна, так что запомните её получше.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.