Консольные приложения и параметры программы
READ и READLN
Процедура 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>:
Параметры консольного приложения
Нередко системные консольные программы вызываются с какими-то параметрами. Например, в 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, чтобы программа не закрылась, пока не захочет пользователь.
Сохраните проект и запустите его. Он загрузится без параметров, вам придется ввести оба числа вручную. Введите числа, полюбуйтесь на результат и закройте программу. Теперь загрузим ее с параметрами. Для этого нажмите "Пуск -> Выполнить", нажмите кнопку "Обзор", найдите и откройте наш проект, допишите после его имени один или два параметра, например, так:
Как видите, в качестве параметров я указал два числа: 12 и 24. Программа не станет запрашивать у меня данные, а сразу выведет результат:
Поэкспериментируйте с программой, вызывая с различным количеством параметров.
Как уже говорилось, функции ParamCount и ParamStr можно использовать в любой программе, не обязательно консольной.