Глава 6В этой главе: Базовые средства ввода-выводаВвод из STDINЧтение со стандартного ввода (через Perl-дескриптор файла stdin) несложная задача. Мы уже делали это в операции <stdin>. Выполняя эту операцию в скалярном контексте, мы получаем следующую строку ввода* (а если строк больше нет то значение undef):$а = <STDIN>; # прочитать следующую строкуВыполнение в списочном контексте дает все оставшиеся строки в виде списка, каждый элемент которого представляет собой одну строку, включающую завершающий символ новой строки. Напомним: @а = <STDIN>;Как правило, при разработке программы приходится решать задачу чтения всех строк по одной с последующим выполнением над каждой из них каких-либо операций. Вот широко используемый метод решения этой задачи: while (defined($line_ = <STDIN>)) ( # здесь обработать $line )Пока есть непрочитанные строки, в результате выполнения операции <stdin> получается определенное значение, и выполнение цикла продолжается. Если строк для чтения у <stdin> больше нет, эта операция возвращает значение undef и завершает цикл.* До символа новой строки или того, что вы присвоили переменной $/.Операция чтения скалярного значения из <stdin> в $_ и использование этого значения в качестве переменной цикла (как в предыдущем примере) выполняется довольно часто, поэтому в Perl предусмотрена для этого случая специальная сокращенная запись. Если в выражении для проверки цикла указан только оператор чтения со стандартного ввода (нечто вроде <...>), то Perl автоматически копирует строку, которая считывается, в переменную $_.while (<STDIN>) { # как "while(defined($_ = <STDIN>_) "chomp; # как "chomp($_)" # здесь выполняются другие операции с $_ )Поскольку переменная $_ по умолчанию используется во многих операциях, таким способом вы можете значительно сократить объем набираемого текста.Ввод из операции "ромб" Другой способ чтения входной информации состоит в использовании операции "ромб" (О). По принципу работы она похожа на <stdin> тем, что возвращает в скалярном контексте одну строку (или undef, если все строки прочитаны), а в списочном контексте все оставшиеся строки. В отличие, однако, от операции <stdin> операция "ромб" получает данные из файла или файлов, заданных в командной строке при вызове Perl-программы. Пусть, например, у вас есть программа kitty:#!/usr/bin/peri while (<>) ( print $_; i и вы вызываете ее так: kitty filel file2 file3 Операция "ромб" читает сначала все строки первого файла, затем все строки второго и, наконец, все строки третьего файла. Значение undef возвращается только тогда, когда будут прочитаны все строки всех файлов. Как видите, программа kitty немного похожа на UNIX-команду cat тем, что посылает все строки указанных файлов по очереди на стандартный вывод. Если, как в cat, имена файлов в командной строке не указаны, операция "ромб" автоматически читает данные со стандартного ввода.В ходе своего выполнения операция "ромб" не рассматривает аргументы командной строки непосредственно, а работает с массивом @argv. Это специальный массив, инициализируемый интерпретатором Perl в соответствии с аргументами командной строки. Каждый аргумент заносится в отдельный элемент этого массива. Интерпретировать этот массив можно как угодно*. Можно даже определить этот массив в своей программе и заставить операцию "ромб" работать с этим новым списком, а не с аргументами командной строки, например:@ARGV = ("aaa","bbb","ccc"); while t В главе 10 мы увидим, как можно открывать и закрывать определенные файлы в определенное время. Впрочем, мы уже использовали этот метод в некоторых наших слепленных на скорую руку программах.Вывод в STDOUTДля посылки каких-либо данных на стандартный вывод в Perl служат функции print и printf. Давайте посмотрим, как они работают.Функция print обычный выводМы уже пользовались функцией print, направляя текст на стандартный вывод. Давайте остановимся на этом вопросе несколько подробнее.Функция print получает список строк и посылает их по очереди на стандартный вывод, не добавляя никаких промежуточных или конечных символов. Возможно, не совсем очевидно, что print это просто функция, которая принимает список аргументов и возвращает определенное значение подобно любой другой функции. Другими словами,$а = print("hello ", "world", "\n");это еще один вариант вывода приветствия hello, world. Возвращаемое значение функции print "истина" или "ложь", говорящее соответственно об успешном и неудачном выполнении. Она почти всегда выполняется успешно, если только не произошла ошибка ввода-вывода, поэтому в рассматриваемом случае $а обычно бывает равно 1. Иногда в print нужно вводить круглые скобки, как показано в данном примере, особенно когда первый элемент, который вы хотите вывести, сам начинается с левой скобки:print (2+3),"hello"; # неверно! Выводит 5, игнорируя "hello" print ((2+3),"hello"); # верно, выводит Shello print 2+3,"hello"; # тоже верно, выводит Shello* Стандартный дистрибутив Perl содержит модули getopt-подобного синтаксического анализа аргументов командной строки Perl-программы. Информация об этой библиотеке есть в книге Programming Perl и на man-странице perlmodlib(l).Функция printf форматированный выводВероятно, вы захотите в большей степени контролировать выводимые данные, чем это позволяет функция print. Возможно, вы привыкли к форматированному выводу С-функции printf. Спешим обрадовать: в Perl есть почти сравнимая операция с таким же именем.Функция printf принимает список аргументов (заключенный в необязательные круглые скобки, как и в случае использования функции print). Первый аргумент строка управления форматом, указывающая, как выводить остальные аргументы. Если вы не знакомы со стандартной функцией printf, обратитесь к man-странице printf(3) или perlfunc{\), если она у вас есть, или к главе 3 книги Programming Perl.Пример: printf "%15s %5d %10.2f\n", $s, $n, $r; Эта функция выводит $s в 15-символьном поле, затем пробел, затем $п как десятичное целое в 5-символьном поле, затем еще один пробел, затем $г как значение с плавающей запятой с двумя десятичными знаками в 10-символьном поле и, наконец, символ новой строки.Упражнения Ответы к упражнениям даны в приложении А. 1. Напишите программу, которая работает аналогично команде cat, но изменяет на обратный порядок следования всех строк всех файлов, указанных в командной строке, или всех строк, поступающих со стандартного ввода, если файлы не указаны. (В некоторых системах есть подобная утилита; она называется tac.)2. Измените программу из предыдущего упражнения таким образом, чтобы в каждом файле, указанном в командной строке, порядок строк изменялся на обратный индивидуально. (Да-да, вы можете сделать это, пользуясь тем материалом, который до сих пор изучили, даже не возвращаясь к обзору возможностей языка Perl, приведенному в главе 1.)3. Напишите программу, которая читает список строковых значений (каждое из которых занимает отдельную строку) и выводит эти строки в 20-символьном столбце с выравниванием справа. Например, при вводе строк hello и good-bye они выводятся в 20-символьном столбце с выравниванием справа. (Добейтесь, чтобы ваша программа действительно использовала 20-символьный столбец, а не 21-символьный. Это весьма распространенная ошибка.)4. Измените программу из предыдущего упражнения таким образом, чтобы пользователь мог выбирать ширину столбца. Например, при вводе строк 20, hello и good-bye получатся те же результаты, что и в предыдущем упражнении, а ввод 30, hello, good-bye обеспечит размещение hello и good-bye в 30-символьном столбце. |