Освоить работу с консольными приложениями и с параметрами программы.
На сегодняшний день о программировании на Lazarus существует очень мало книг на русском языке, и все они описывают работу в основном, с консольными приложениями, хотя особой надобности в консолях сейчас нет. Но и совсем обойти эту тему нельзя. Что же такое консольное приложение?
Консольным приложением называется программа, которая не имеет графического интерфейса - окон, и которая работает в текстовом режиме в черно-белой консоли. Команды в такой программе приходиться вводить с клавиатуры, результаты работы консольные приложения также выводят на экран в текстовом режиме.
Если вы пользуетесь операционной системой Windows, то нажмите на "Пуск" и выберите команду "Выполнить". В открывшемся окне наберите
cmd
и нажмите <Enter>. Откроется командная консоль, в которой команды нужно вводить в текстовом режиме:
(рис 21.1) Консоль cmd.exe
Собственно, вы видите окно предка Windows - операционной системы MS-DOS. Именно так выглядел экран с загруженной ОС MS-DOS, и управлять ею приходилось, вручную набивая всевозможные команды. Это уже позже корпорация Microsoft навесила на ядро MS-DOS всевозможные драйверы и утилиты, снабдила его графическим оконным интерфейсом, и появилась сначала полуграфическая ОС Windows 3.10 (русский вариант был 3.11 версии), а затем и целиком графическая Windows 95. Но к консольному ядру системы можно обращаться и в современных ОС, в Windows для этого используется программа cmd.exe, а в ОС Linux - терминал.
Все языки высокого уровня позволяют делать и консольные приложения, другое дело - зачем? Подавляющее большинство современных программ имеет графический интерфейс, который мы с вами создавали с самой первой лекции. А консольные приложения делаются в основном, системными программистами. Несмотря на то, что Object Pascal обладает для этого всеми необходимыми инструментами, системщики обычно пользуются такими языками, как Ассемблер, C, реже - C++. Но все же знать, как создаются консольные приложения нужно, поэтому данную лекцию мы посвящаем им.
Создать консольное приложение можно разными способами, но проще всего так. Откройте Lazarus. Командой "Проект -> Закрыть проект" закройте текущий проект, автоматически появится окно Мастера создания проекта. В нем нажмем кнопку "Новый проект". Появится окно создания проекта, в котором можно выбрать "Программа" или "Консольное приложение". Если мы выберем "Программа", то будет создан модуль с минимальным кодом. Если же мы выберем "Консольное приложение", то кода будет больше, так как при этом создается программа с новым классом, производным от TCustomApplication. TCustomApplication обеспечивает хорошую основу и делает программирование утилит командной строки довольно простым. Например, проверку опций командной строки, написание справки, проверку переменных окружения и обработку исключений.
Все программы LCL автоматически это используют.
Но нам не нужно использовать возможности класса TCustomApplication, мы делаем простую консольную программу, поэтому в окне создания проекта мы выбираем "Программа". Сформируется проект, а в Редакторе исходного кода будет минимум текста:
program Project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
begin
end.
Обратите внимание, если нам нужно подключить к программе какие то модули, то делать это нужно до комментария
{ you can add units after this };
В этом случае мы ставим запятую после указанного модуля Classes и добавляем свои модули. Завершающая точка с запятой стоит после комментария, нам её ставить не нужно.
Свой код мы будем писать между скобками
begin
end.
А если нам потребуется указать глобальные константы, переменные или сделать объявления процедур и функций, то все это делается до begin.
Для примера мы создадим простое приложение, а по ходу дела, познакомимся с инструментами ввода-вывода информации в консольных приложениях.
Процедура Write предназначена для вывода информации на экран. Она имеет следующий синтаксис:
procedure Write(var F:Text; Args:Arguments);
Действует процедура следующим образом. В скобках мы можем указать какой-то текст, вывести содержимое переменных. Например:
write('Всем привет!!!');
write('Переменная a = ', a, '; переменная b = ', b);
После вывода информации на экран курсор остается на той же строчке, в позиции, где он оказался после вывода последнего символа.
Процедура Writeln действует точно также, но после вывода последнего символа курсор переходит на начало следующей строки.
Для ознакомления с процедурами создайте новый проект "Программа". Модуль можно не переименовывать, просто сохраните его в папку 21-01. Полный текст модуля следующий:
program project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
var a, b: Integer;
begin
a:= 5;
b:= 10;
writeln('Всем привет!!!');
writeln('Переменная a = ', a, '; переменная b = ', b);
readln();
end.
Обратите внимание: раздел переменных var мы указали до служебного слова begin, то есть, переменные a и b в пределах модуля являются глобальными. Далее мы присвоили переменным значения, затем вывели на экран приветствие, а потом содержимое переменных. На процедуру readln() пока не обращайте внимания, она нужна только, чтобы программа не закрылась сразу же после вывода текста, а была на экране, пока мы не нажмем <Enter>. Сохраните проект и запустите его на выполнение. И сразу же мы видим недостаток: вместо русских букв выходит нечто, что в Интернете называют "кракозябры":
(рис 21.2) Неправильный вывод кириллицы в консольной программе
В лекции №5 мы упоминали, что в консольных приложениях Windows принято использовать кодировку CP866, тогда как в графических приложениях используется CP1251 и Юникод. Отсюда и "кракозябры". В Linux и Unix таких проблем нет. Однако решить эту проблему совсем несложно. Нажмите <Enter>, чтобы закрыть консоль, и вернитесь в Редактор кода. Щелкните по окну с кодом правой кнопкой мыши, и в открывшемся контекстном меню выберите команду "Параметры файла -> Кодировка -> CP866". Откроется окно смены кодировки, нам надо нажать кнопку "Изменить файл". Снова запустите программу на выполнение - теперь с кодировкой полный порядок:
(рис 21.3) Правильный вывод кириллицы в консольной программе
Процедура Read предназначена для ввода информации в программу, точнее, в переменные. Процедура работает следующим образом:
read(Переменная1, Переменная2, …, ПеременнаяN);
То есть, в качестве параметров мы указываем одну или несколько разделенных запятыми переменных. Когда программа доходит до этого места, то ожидает от пользователя ввода данных. Пользователь должен ввести данные такого же типа, как у соответствующих переменных. Если переменных несколько, то соответствующие значения нужно вводить, разделяя их пробелами. Например, если есть переменная целого типа i, и вещественная переменная r, то при выполнении инструкции
read(i, r);
произойдет вот что: программа приостановит свою работу, ожидая от пользователя ввода данных. Пользователь должен ввести целое и вещественное числа, разделенные пробелом, и нажать <Enter>. Например, пользователь ввел:
12 3.45
Как только он нажмет <Enter>, в переменную i попадет число 12, а в r - число 3,45. Если пользователь введет некорректные данные, не соответствующие типу переменной, то возникает ошибка и программа аварийно завершает работу.
Пользователь может ввести больше данных, чем указано переменных в процедуре read. В этом случае, оставшиеся данные будут обработаны следующей процедурой read. Например, пользователь ввел:
1 23 456
и нажал <Enter>. Эти данные могут быть обработаны следующими инструкциями:
read(a, b);
read(c);
Процедура Readln работает также. Отличие заключается в том, что если пользователь ввел больше данных, то readln не передает лишние данные в следующую инструкцию readln, а попросту обрубает их. То есть, если изменить предыдущий пример:
readln(a, b);
read(c);
то в a и b попадут числа 1 и 23, после чего программа будет ожидать следующих данных, а число 456 потеряется.
Если указать read или readln без параметров, например, так:
readln();
то программа просто перейдет в режим ожидания, пока пользователь не введет <Enter>. В конце консольных приложений всегда желательно указывать такую пустую readln, иначе программа просто мигнет и выключится, не дав пользователю увидеть результаты работы. Или можно как-то иначе обеспечить работу программы до тех пор, пока пользователь сам не захочет ее закрыть. Например, иногда программисты выводят сообщение типа "Продолжить работу программы? 0-нет, 1-да". Если пользователь введет 0, то программа завершится, а если 1, то продолжит работу. Какой способ использовать - дело ваше.
Чтобы пользователь понимал, чего от него хочет программа, перед каждой инструкцией read или readln следует с помощью write или writeln выводить поясняющий текст.
Вернемся к нашей программе, и немного изменим код (между begin и end.):
begin
write('Введите первое целое число: ');
readln(a);
write('Введите второе целое число: ');
readln(b);
writeln('Результат:');
writeln('Переменная a = ', a, '; переменная b = ', b);
readln();
end.
Теперь программа выводит запрос "Введите первое число:", и замирает, ожидая от пользователя ввода данных. После того, как он введет число и нажмет <Enter>, программа таким же образом запросит второе число. Затем она выведет результат, и будет ожидать, пока пользователь не нажмет <Enter>:
(рис 21.4) Результат работы программы
Нередко системные консольные программы вызываются с какими-то параметрами. Например, в Windows можно нажать "Пуск -> Выполнить" и указать следующую команду:
ping 127.0.0.1 -t
В результате будет запущена консольная утилита ping.exe, которая делает трассировку (обмен данными) с указанным IP-адресом. Таким образом, проверяют, есть ли связь с данным адресом. В примере программа запускается с двумя параметрами. Первым параметром является IP-адрес 127.0.0.1 - это адрес локальной машины, обращаясь к 127.0.0.1, вы обращаетесь к своему же компьютеру. Вторым параметром является
-t
Этот параметр указывает утилите, что не следует завершать обмен данными, пока пользователь сам не прервет работу программы. Если не указать -t, программа сделает 4 попытки отправить данные, после чего завершит свою работу. С параметром -t программа будет работать, пока пользователь не нажмет <Ctrl+C>.
Возможно, когда-нибудь и нам потребуется создать программу (не обязательно консольную), умеющую принимать и обрабатывать параметры. Для обработки параметров используются две функции: ParamCount и ParamStr.
ParamCount возвращает количество параметров, переданных в программу.
ParamStr(i) возвращает параметр под индексом i - индексация начинается с 1. Например, вывести на экран первый и последний параметры можно так:
ShowMessage('Первый параметр: ' + ParamStr(1);
ShowMessage(Последний параметр: ' + ParamStr(ParamCount);
Однако имейте в виду, что в любой программе, консольной или обычной, даже запущенной совсем без всяких параметров, доступен и "нулевой" параметр ParamStr(0) - в нем всегда находятся адрес и имя файла программы.
Чтобы закрепить материал, давайте снова изменим нашу программу, получая и обрабатывая параметры. Мы сделаем так, что её можно будет использовать без параметров, тогда пользователь будет вводить числа прямо в программе. Можно будет загрузить программу с одним параметром, тогда это значение попадет в переменную a, а число для b пользователю придется вводить вручную. И, наконец, программу можно будет загружать с множеством параметров, при этом первые два попадут в a и b, остальные будут проигнорированы. Не забывайте, что тип данных должен соответствовать переменным, то есть один параметр, или первых два параметра должны быть обязательно целыми числами. Иначе программа даже не запустится, а просто выведет сообщение об ошибке.
Имейте в виду, что все параметры, даже числа, вводятся в виде текста, так что для работы с целыми числами нам придется использовать функции IntToStr и StrToInt. А обе эти функции описаны в модуле SYSUTILS, который нам придется подключить в разделе uses. Вот полный листинг программы:
program project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
var a, b: integer;
begin
//если параметров вообще нет:
if ParamCount = 0 then begin
write('Введите первое целое число: ');
readln(a);
write('Введите второе целое число: ');
readln(b);
end
//если только один параметр:
else if ParamCount = 1 then begin
a:= StrToInt(ParamStr(1));
write('Введите целое число: ');
readln(b);
end
//если параметров больше одного:
else begin
a:= StrToInt(ParamStr(1));
b:= StrToInt(ParamStr(2));
end;
//теперь вывод результатов:
writeln('Всего параметров: ' + IntToStr(ParamCount));
writeln('Запущена программа: ' + ParamStr(0));
writeln('Переменная a = ', a, '; переменная b = ', b);
readln();
end.
Обратите внимание, после модуля Classes мы указали модуль SysUtils. Далее, мы обеспечили ввод данных в a и b в случаях, если параметров вообще нет, если есть только один параметр, и если параметров больше, чем один. В конце мы выводим общее количество указанных параметров, нулевой параметр с указанием адреса и файла программы, и затем указываем значения переменных. В заключение указываем пустой readln, чтобы программа не закрылась, пока не захочет пользователь.
Сохраните проект и запустите его. Он загрузится без параметров, вам придется ввести оба числа вручную. Введите числа, полюбуйтесь на результат и закройте программу. Теперь загрузим ее с параметрами. Для этого нажмите "Пуск -> Выполнить", нажмите кнопку "Обзор", найдите и откройте наш проект, допишите после его имени один или два параметра, например, так:
(рис 21.5) Указание параметров программы
Как видите, в качестве параметров я указал два числа: 12 и 24. Программа не станет запрашивать у меня данные, а сразу выведет результат:
(рис 21.6) Результат работы программы
Поэкспериментируйте с программой, вызывая с различным количеством параметров.
Как уже говорилось, функции ParamCount и ParamStr можно использовать в любой программе, не обязательно консольной.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.