Perl Learning (5) —— 输入与输出
2011-01-31 22:19
387 查看
2011-01-31 wcdj
(1) 读取标准输入
(2) 钻石操作符输入
(3) 调用参数
(4) 输出到标准输出
(5) 使用printf格式化输出
(6) 数组和printf
(7) 文件句柄
(8) 打开和关闭文件句柄
(9) 用die处理严重错误
(10) 使用warn输出警告信息
(11) 使用文件句柄
(12) 改变默认的文件输出句柄
(13) 使用say来输出
(1) 读取标准输入
“行输入”<STDIN>操作符
【1】在标量上下文中
调用“行输入”操作符,将会返回标准输入中的一行。
$line = <STDIN>; # 读取下一行
chomp($line); # 截掉最后的换行符
简写:
chomp($line = <STDIN>);# 习惯用法,效果同上
注意:如果读到文件结尾(end-of-file),“行输入”操作符就会返回undef —— 这样的设计是为了配合循环使用,可以自然地跳出循环。
注意:
[1] 只有当while循环的条件表达式里只有“行输入”操作符的前提下,这个简写才起作用。假如条件表达式里放了其他的东西,它就无法按你的预期运行了。
[2] “行输入”操作符(<STDIN>)和Perl的“老地方”变量($_)之间并没有什么关联。只是在这个简写里,输入的内容会恰好存储在$_变量中而已。
【2】在列表上下文中
调用“行输入”操作符,它会返回一个列表,其中包含(其余)所有的输入内容,每个列表的元素代表一行输入内容。
注意:while循环和foreach循环的区别
两者不同之处在于它们背后的运作方式。
在while循环里,Perl会读取一行输入,把它存入某个变量并且执行循环的主体。接下来,它会回头去寻找其他的输入行。
在foreach循环里,“行输入”操作符会在列表上下文中执行(因为foreach需要逐项处理列表的内容)。为此,在循环能够开始执行之前,它必须先将输入全部读进来。
建议:最好的做法,对于大文件,通常是尽量使用while循环的简写,让它每次处理一行。
(2) 钻石操作符输入
还有另一种读取输入的方法,就是使用钻石操作符<>。
它能让程序在处理调用参数的时候,提供类似于标准Unix工具程序的功能。
程序的调用参数(invocation arguments)通常是命令行上跟在程序名后面的几个“单词”。
注意:
[1] 连字符(-)当作参数,代表标准输入。
[2] 让程序以这种方式运行的好处,就是你可以在运行时指定程序的输入源。
注意:
[1] 钻石操作符是“行输入”操作符的特例。不过它并不是从键盘取得输入,而是从用户指定的位置读取。
[2] 钻石操作符只有在碰到所有输入的结尾时,才会返回undef。(然后就会跳出while循环)
[3] 由于钻石操作符通常会处理所有的输入,所以当它在程序里出现好几次时,通常是错误的。
(3) 调用参数
钻石操作符其实不会去检查调用参数,它的参数其实是来自@ARGV数组。
注意:
[1] 这个数组是由Perl解释器事先建立的特殊数组,其内容就是由调用参数组成的列表。在程序开始运行时,@ARGV里就已经塞满了调用参数。
[2] 如果@ARGV是空列表,就会改用标准输入流。
[3] 只要尚未使用钻石操作符,你就可以对@ARGV动点手脚。
(4) 输出到标准输出
print操作符会读取一个列表里的所有值,并把每一项依次送到标准输出。
print @array;# 元素之间没有空格
print "@array";# 数组所有元素之间用空格分开
注意:因为Perl把数组内插到字符串中时,会在每个元素之间加上空格。
由于print处理的是待打印的字符串列表,因此它的参数会在列表上下文中执行。而钻石操作符(“行输入”操作符的特殊形式)在列表上下文中会返回由许多输入行组成的列表,所以它们彼此可以配合工作。
print <>;# 和Unix下的'cat'命令功能差不多
print sort <>;# 和Unix下的'sort'命令功能差不多
注:现在你可以用Perl重写所有的Unix工具程序。
注意:print后面的括号可有可无 —— 除非这样做会改变表达式的意义,否则Perl里的括号可以省略。
print (2+3)*4;# 输出5
print ( (2+3)*4 )# 输出20
(5) 使用printf格式化输出
常用的转换(conversion):
注意:
[1] 对齐方向:负数(左对齐);正数(右对齐)。
[2] %%,不会输出(参数)列表中的任何元素。
(6) 数组和printf
动态产生格式字符串。
注意:在标量上下文中,用了一次@items以取得它的长度,然后又在列表上下文中用了它一次以取得它的内容。(上下文的重要性)
(7) 文件句柄
建议:使用全大写字母来命名文件句柄。
【六个特殊文件句柄】(Perl保留的)
STDIN、STDOUT、STDERR、DATA、ARGV和ARGVOUT。
(8) 打开和关闭文件句柄
Perl提供的三种文件句柄STDIN、STDOUT和STDERR,都是由产生Perl进程的父进程(可能是shell)自动打开的文件或设备。
当你需要其他的文件句柄时,请使用open操作符。
open CONFIG, "filename";
open CONFIG, "<filename";# 从文件中输入
open BEDROCK, ">filename";#输出到文件(“>”会重新创建文件)
open LOG, ">>logfile";#输出到文件(“>>”追加的方式)
在Perl 5.6之后,open另有一种使用三个参数的写法。
open CONFIG, "<", "filename";
不正确的文件句柄
open的返回值来判断句柄是否正确:
my $success = open LOG, ">>logfile";# 捕获返回值
if (! $success) {
# open操作失败
# ...
}
关闭文件句柄
当你不再需要某个文件句柄时,可以用close操作符来关闭它。
close CONFIG;
建议:请为每个open搭配一个close。最好是在每个文件句柄用完之后就立刻关闭它,哪怕程序马上就结束了。
注:
关闭文件句柄会:[1] 刷新输出缓冲 [2] 释放该文件上的任何锁。
(9) 用die处理严重错误
当Perl遇到严重错误(fatal error)时,程序应该终止运行,并用错误信息告知原因。
die函数会输出你指定的信息(到为这类信息预留的标准错误流中),并且让你的程序立刻终止,并返回不为零的退出码。
if (! open LOG, ">>logfile") {
die "Cannot create logfile: $!";
}
注意:
[1] $! 代表:可读的系统出错信息。当系统拒绝我们所请求的服务时,$! 会给我们一个理由。—— 即,解释性的系统错误信息就保存在Perl的特殊变量$!中。
[2] 只有在系统服务请求失败后的瞬间,$! 的值才会有用。如果操作成功了,就不会在$!里留下任何有用的信息。
[3] die还会自动将Perl程序名和行号附加在错误信息的后面。
(10) 使用warn输出警告信息
warn函数和die函数的区别:不同之处在于最后一步,warn不会终止程序的运行。
(11) 使用文件句柄
当文件句柄以读取模式打开后,可以从它读取一行数据,就像从STDIN读取标准输入流一样。
写入或是添加模式打开的文件句柄可以在print或printf函数中使用。—— 使用时,请直接将它放在关键字之后、参数列表之前。
(12) 改变默认的文件输出句柄
默认情况下,假如不为print或是printf指定文件句柄,它的输出就会送到STDOUT。
不过,你可以使用select操作符来改变默认的文件句柄。
建议:当你所指定的默认文件句柄使用完毕之后,最好把它设回原先的默认值STDOUT来。
注意:将特殊变量$| 设定为1,就会使当前的默认文件句柄在每次进行输出操作后,立刻刷新缓冲区。
(13) 使用say来输出
Perl 5.10从正在开发的Perl 6 中借来了say这个函数。
它的功能和print函数差不多,但是会在每行输出的结尾自动加上换行符。
use 5.010;
say "Hello!";# 比print和/n省掉4次按键
等价于:
print "Hello/n";
(1) 读取标准输入
(2) 钻石操作符输入
(3) 调用参数
(4) 输出到标准输出
(5) 使用printf格式化输出
(6) 数组和printf
(7) 文件句柄
(8) 打开和关闭文件句柄
(9) 用die处理严重错误
(10) 使用warn输出警告信息
(11) 使用文件句柄
(12) 改变默认的文件输出句柄
(13) 使用say来输出
(1) 读取标准输入
“行输入”<STDIN>操作符
【1】在标量上下文中
调用“行输入”操作符,将会返回标准输入中的一行。
$line = <STDIN>; # 读取下一行
chomp($line); # 截掉最后的换行符
简写:
chomp($line = <STDIN>);# 习惯用法,效果同上
注意:如果读到文件结尾(end-of-file),“行输入”操作符就会返回undef —— 这样的设计是为了配合循环使用,可以自然地跳出循环。
#!/usr/bin/perl while (defined($line = <STDIN>)) { print "I saw $line"; } #简写: #!/usr/bin/perl while (<STDIN>) {# 条件简写 print "I saw $_";# 老地方$_ }
注意:
[1] 只有当while循环的条件表达式里只有“行输入”操作符的前提下,这个简写才起作用。假如条件表达式里放了其他的东西,它就无法按你的预期运行了。
[2] “行输入”操作符(<STDIN>)和Perl的“老地方”变量($_)之间并没有什么关联。只是在这个简写里,输入的内容会恰好存储在$_变量中而已。
【2】在列表上下文中
调用“行输入”操作符,它会返回一个列表,其中包含(其余)所有的输入内容,每个列表的元素代表一行输入内容。
#!/usr/bin/perl #while (<STDIN>) {# 简写 # print "I saw $_";# 老地方S_ #} foreach (<STDIN>) { print "I saw $_"; }
注意:while循环和foreach循环的区别
两者不同之处在于它们背后的运作方式。
在while循环里,Perl会读取一行输入,把它存入某个变量并且执行循环的主体。接下来,它会回头去寻找其他的输入行。
在foreach循环里,“行输入”操作符会在列表上下文中执行(因为foreach需要逐项处理列表的内容)。为此,在循环能够开始执行之前,它必须先将输入全部读进来。
建议:最好的做法,对于大文件,通常是尽量使用while循环的简写,让它每次处理一行。
(2) 钻石操作符输入
还有另一种读取输入的方法,就是使用钻石操作符<>。
它能让程序在处理调用参数的时候,提供类似于标准Unix工具程序的功能。
程序的调用参数(invocation arguments)通常是命令行上跟在程序名后面的几个“单词”。
注意:
[1] 连字符(-)当作参数,代表标准输入。
[2] 让程序以这种方式运行的好处,就是你可以在运行时指定程序的输入源。
#!/usr/bin/perl #while (<STDIN>) {# 简写 # print "I saw $_";# 老地方S_ #} #foreach (<STDIN>) { # print "I saw $_"; #} while (defined($line = <>)) { chomp($line); print "It was $line that I saw!/n"; } #简写: while (<>) { chomp;# 使用chomp的默认用法:不加参数时,chomp会直接作用在$_上。 print "It was $_ that I saw!/n"; }
注意:
[1] 钻石操作符是“行输入”操作符的特例。不过它并不是从键盘取得输入,而是从用户指定的位置读取。
[2] 钻石操作符只有在碰到所有输入的结尾时,才会返回undef。(然后就会跳出while循环)
[3] 由于钻石操作符通常会处理所有的输入,所以当它在程序里出现好几次时,通常是错误的。
(3) 调用参数
钻石操作符其实不会去检查调用参数,它的参数其实是来自@ARGV数组。
注意:
[1] 这个数组是由Perl解释器事先建立的特殊数组,其内容就是由调用参数组成的列表。在程序开始运行时,@ARGV里就已经塞满了调用参数。
[2] 如果@ARGV是空列表,就会改用标准输入流。
[3] 只要尚未使用钻石操作符,你就可以对@ARGV动点手脚。
foreach (@ARGV) { print "$_/n"; } @ARGV = qw# filename #;# 强制让钻石操作符读取我们指定的文件 while (<>) { chomp; print "It was $_ that I saw!/n"; }
(4) 输出到标准输出
print操作符会读取一个列表里的所有值,并把每一项依次送到标准输出。
print @array;# 元素之间没有空格
print "@array";# 数组所有元素之间用空格分开
注意:因为Perl把数组内插到字符串中时,会在每个元素之间加上空格。
由于print处理的是待打印的字符串列表,因此它的参数会在列表上下文中执行。而钻石操作符(“行输入”操作符的特殊形式)在列表上下文中会返回由许多输入行组成的列表,所以它们彼此可以配合工作。
print <>;# 和Unix下的'cat'命令功能差不多
print sort <>;# 和Unix下的'sort'命令功能差不多
注:现在你可以用Perl重写所有的Unix工具程序。
注意:print后面的括号可有可无 —— 除非这样做会改变表达式的意义,否则Perl里的括号可以省略。
print (2+3)*4;# 输出5
print ( (2+3)*4 )# 输出20
(5) 使用printf格式化输出
$user = wcdj; $days_to_die = 30; printf "Hello, %s; your password expires in %d days!/n", $user, $days_to_die;
常用的转换(conversion):
%g —— 要输出恰当的数值形式,它会按需求自动选择浮点数、整数、指数形式 printf "%g %g %g/n", 5/2, 51/17, 51**17;# 2.5 3 1.0683e+29 %d —— 输出十进制的整数,它会舍去小数点之后的数字(注意:它会无条件舍去,而非四舍五入) printf "in %d days!/n", 17.85;# in 17 days! %f —— 输出浮点数,会按需要四舍五入 printf "%12f/n", 6*7+2/3; # ^^^42.666667 printf "%12.3f/n", 6*7+2/3; # ^^^^^^42.667 printf "%12.0f/n", 6*7+2/3; # ^^^^^^^^^^43 %s —— 字符串内插 printf "%10s/n", "wcdj";# ^^^^^^wcdj ("^"表示空格)
注意:
[1] 对齐方向:负数(左对齐);正数(右对齐)。
[2] %%,不会输出(参数)列表中的任何元素。
(6) 数组和printf
动态产生格式字符串。
my @items = qw( wcdj gerry yj ); my $format = "The items are:/n" . ("%10s/n" x @items);# x操作符 print "the format is >>$format<</n";# 用于调试 printf $format, @items;
注意:在标量上下文中,用了一次@items以取得它的长度,然后又在列表上下文中用了它一次以取得它的内容。(上下文的重要性)
(7) 文件句柄
建议:使用全大写字母来命名文件句柄。
【六个特殊文件句柄】(Perl保留的)
STDIN、STDOUT、STDERR、DATA、ARGV和ARGVOUT。
(8) 打开和关闭文件句柄
Perl提供的三种文件句柄STDIN、STDOUT和STDERR,都是由产生Perl进程的父进程(可能是shell)自动打开的文件或设备。
当你需要其他的文件句柄时,请使用open操作符。
open CONFIG, "filename";
open CONFIG, "<filename";# 从文件中输入
open BEDROCK, ">filename";#输出到文件(“>”会重新创建文件)
open LOG, ">>logfile";#输出到文件(“>>”追加的方式)
在Perl 5.6之后,open另有一种使用三个参数的写法。
open CONFIG, "<", "filename";
不正确的文件句柄
open的返回值来判断句柄是否正确:
my $success = open LOG, ">>logfile";# 捕获返回值
if (! $success) {
# open操作失败
# ...
}
关闭文件句柄
当你不再需要某个文件句柄时,可以用close操作符来关闭它。
close CONFIG;
建议:请为每个open搭配一个close。最好是在每个文件句柄用完之后就立刻关闭它,哪怕程序马上就结束了。
注:
关闭文件句柄会:[1] 刷新输出缓冲 [2] 释放该文件上的任何锁。
(9) 用die处理严重错误
当Perl遇到严重错误(fatal error)时,程序应该终止运行,并用错误信息告知原因。
die函数会输出你指定的信息(到为这类信息预留的标准错误流中),并且让你的程序立刻终止,并返回不为零的退出码。
if (! open LOG, ">>logfile") {
die "Cannot create logfile: $!";
}
注意:
[1] $! 代表:可读的系统出错信息。当系统拒绝我们所请求的服务时,$! 会给我们一个理由。—— 即,解释性的系统错误信息就保存在Perl的特殊变量$!中。
[2] 只有在系统服务请求失败后的瞬间,$! 的值才会有用。如果操作成功了,就不会在$!里留下任何有用的信息。
[3] die还会自动将Perl程序名和行号附加在错误信息的后面。
(10) 使用warn输出警告信息
warn函数和die函数的区别:不同之处在于最后一步,warn不会终止程序的运行。
(11) 使用文件句柄
当文件句柄以读取模式打开后,可以从它读取一行数据,就像从STDIN读取标准输入流一样。
if (! open FILE, "<filename") { die "Cannot read file: $!"; } while (<FILE>) { chomp; print "$_/n"; }
写入或是添加模式打开的文件句柄可以在print或printf函数中使用。—— 使用时,请直接将它放在关键字之后、参数列表之前。
if (! open LOG, ">>logfile") { die "Cannot create logfile: $!"; } $name = "wcdj"; print LOG "2011-2-1/n"; printf LOG "My name is %s./n", $name;
(12) 改变默认的文件输出句柄
默认情况下,假如不为print或是printf指定文件句柄,它的输出就会送到STDOUT。
不过,你可以使用select操作符来改变默认的文件句柄。
if (! open LOG, ">>logfile") { die "Cannot create logfile: $!"; } $name = "wcdj"; print "2011-2-1/n"; printf "My name is %s./n", $name; select LOG;# 改变默认的文件句柄 print "select used/n"; print "2011-2-1/n"; printf "My name is %s./n", $name; select STDOUT;# 恢复默认句柄 print "select used/n"; print "2011-2-1/n"; printf "My name is %s./n", $name;
建议:当你所指定的默认文件句柄使用完毕之后,最好把它设回原先的默认值STDOUT来。
注意:将特殊变量$| 设定为1,就会使当前的默认文件句柄在每次进行输出操作后,立刻刷新缓冲区。
(13) 使用say来输出
Perl 5.10从正在开发的Perl 6 中借来了say这个函数。
它的功能和print函数差不多,但是会在每行输出的结尾自动加上换行符。
use 5.010;
say "Hello!";# 比print和/n省掉4次按键
等价于:
print "Hello/n";
相关文章推荐
- Perl学习之五:输入与输出
- Perl学习笔记(4)文件的输出输入
- Perl的基本输入输出
- perl学习(5) 输入和输出
- perl系列:输入与输出
- perl的输入与输出
- Perl笔记:04、输入与输出
- leanging perl(二) 输入与输出
- perl输入,排序,输出,一行代码解决所有的问题
- Perl 中的输入与输出
- Perl语言学习笔记 5 输入与输出
- 一行代码解决 perl输入 排序 输出问题
- Perl 语言笔记(4) -- 输入输出
- perl学习——输入和输出
- perl-标准输入与输出
- perl学习(5) 输入和输出
- 输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。
- mybatis 输入映射和输出映射
- 输入三个字符后,按各字符的ASCII码从小到大的顺序输出这三个字符。
- 将多行输入转换成单行输出