Perl入门笔记——输入和输出

Learning Perl 

第五章 输入和输出
读取标准输入,使用行操作符<STDIN>:
$line = <STDIN>;
chomp($line);
如果读到文件结尾,行输入符就会返回undef.
while (defined($line=<STDIN>)) {
  print "I have seen $line.\n";
}
Perl可以将上述定义简写:
while (<STDIN>) {
    print "I have seen $_.\n";
}
行输入操作符<STDIN>与默认变量($_)之间没有关联,只是这个简写里,输入的内容恰好存储在默认变量里面。
for与while的区别,while循环,Perl会读取一行,然后在寻找其他输入行;
for循环会将输入全部读起来。

另外一种读取输入的方法,就是使用钻石操作符<>,它能让程序在处理参数时,提供类似Unix工具的功能。
程序调用参数(invocation argument)通常是命令行上跟着程序后面的几个单词。
$./my_program.pl cao qing
如果把连字符当作参数,则表示从标准输入读取数据。假如调用参数cao-qing。程序会先处理cao,然后处理标准输入流中提供的数据,最后才是qing。
可以在程序运行时指定程序的输入源。
钻石操作符是行输入操作符的特例。他不是从键盘取得输入,而是从用户指定位置读取:
while (<>) {
    chomp;
    print "It was $_ that i saw.\n";
}
加入钻石操作符无法打开某个文件读取其中内容时,会出现诊断错误。
钻石操作符不会去检查命令行参数,它的参数来自于@ARGV数组。该数组就是命令行参数列表。
@ARGV列表与其他数组类似,进行同样操作。如果为空列表,则改用标准输入流。
@ARGV = qw (cao qing wang huan);
while (<>) {
  chomp;
  print "I have seen $_.\n";
}
强制让钻石操作符读取上述四个文件。

输出到标准输出
print操作符会读取后续列表中的所有元素。
直接使用数组和使用数组内插是不同的:
print @array;
print "@array";
第一个会一个接一个的打印所有元素;第二个是打印一个字符串。
@array = qw \ cao qing wang huan\;
print @array;
print "\n";
print  "@array";

caoqingwanghuan
cao qing wang huan
print处理的是带打印的字符串列表,所以他的参数在列表上下文执行。而钻石操作符在列表上下文中返回许多输入组成的列表,所以他们之间可以配合工作。
print <>;        #Unix cat
print sort <>;    #Unix sort
print后面的括号可有可无,除非会改变表达式的意义,否则Perl里的括号可以省略。
Perl可以省略括号,但是不要忘记括号的归属,
printf格式化输出
printf需要的参数包括格式化字符串和要输出的数据列表。
元素个数应该和转换的数目一样多,否则无法正常运行。
要输出恰当的数组形式,可以使用%g,它会自动选择浮点数,整数甚至是指数形式。
print "%g %g %g\n", 5/2, 4, 2 ** 10;
%d表示十进制整数,它会无条件阶段,而非四舍五入。
%s代表字符串,他的功能就是字符串内插。
如果宽带字段为负数,则会左对齐。
数组和printf。一般不会把数组当作printf参数。这是因为数组会包含任意数目的元素,而格式化字符串只会用到固定数目的元素。
可以在程序中动态的产生格式字符串:
my @items = qw (cao qing wang huan);
my $format = "The items are: \n" . ("%10s\n" x @items);
print "The format is >>$format<<\n";
printf $format, @items;

The format is >>The items are: 
%10s
%10s
%10s
%10s
<<
The items are: 
       cao
      qing
      wang
      huan
注意上下文的重要性。

文件句柄
文件句柄(filehandle)就是程序里代表Perl进程与外界之间的I/O联系的名称。
可以把文件句柄的引用放在常规的标量变量里,不过喜欢使用裸字(bareword)。
建议使用全大写字母来命名文件句柄。
Perl保留6个特殊文件句柄名:STDIN,STDOUT,STDERR,DATA,ARGV,ARGVOUT。
打开文件句柄
open CONF, 'dino';
open CONF, '< dino';
open CONF, '> fred';
open CONF, '>> logile';
第一行和第二行完全相同,第三行为打开一个文件句柄并输出到新文件fred,第四行已追加的方式打开文件句柄。
可以使用任意的一个标量表达式来代替文件名说明符。
注意大于号后面的空格。
新版的还可以接受三个参数,open CONF, '<', 'dino';
可以更容易区分模式和文件名本身。还有一个好处就是指定编码值。
指定读取的文件为UTF-8编码的:
open CONF, '<:encoding(utf-8)', 'dino';
除了编码之外,数据输入和输出还有其他层可以控制数据转换。
解决回车换行可以借助:crlf层
open BEDROCK, '>:crlf', $filename;
读取DOS风格的文件时,可以:open BEDROCK, "<:crlf", $filename
会自动转换为Unix风格的换行符。

以二进制方式读取文件句柄
Perl5.6以后可以在binmode的第二个参数位置指定层。如果希望输出Unicode到STDOUT,就要确保STDOUT知道如何处理拿到的数据:
binmode STDOUT, ':encoding(UTF-8)';
如果知道传入的是UTF-8编码的字符:
binmode STDIN, ':encoding(UTF-8)';
有问题的文件句柄,可以使用-w和warnings编译指令来启用警告功能。

关闭文件句柄
close BEDROCK;
die处理致命错误,可以能够自己触发致命错误并给出错误信息。
die函数会输出指定信息到标准错误流,并终止程序,返回不为0的状态码。
if (! open LOG, '>>', 'logfile') {
    die "cannot create logfile: $!";
}
open失败,die会终止程序运行。$!就是可读的系统错误信息。
可以用warn发出警告信息,但是不会终止程序运行。
autodie编译指令可以自动检测致命错误。
use autodie;
使用文件句柄
一旦文件句柄以读取模式打开,便可以从他读取一行行数据。
if (! open PASSWD, '<', '/etc/passwd') {
    die "How did you get logged in?($!)";
}
while (<PASSWD>) {
    chomp;
    ...
}
已写入或者添加模式打开的文件句柄可以在print或printf函数中使用。使用时,直接放在函数名之后,参数列表之前。
print LOG "I love you.\n";
print STDERR "I miss you.\n";
改变默认的文件句柄
select BEDROCK;
print "I hope you can love me.\n";
一旦选择用了默认文件句柄,文件会一直往哪里输出。
select LOG;
$| = 1;
select STDOUT;
print LOG "i love you./n";
将数据输出到文件句柄时,默认都会经过缓冲处理,但是只要将默认变量$|设定为1,就会是当前的默认文件句柄在每次输出后立刻刷新缓冲区。
重新打开文件句柄。Perl重新打开文件句柄时,会默认关闭原来那个。


转载于:https://my.oschina.net/u/1449160/blog/201879

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值