$line = <STDIN>; #读取下一行
chomp($line); #去掉最后的换行符
chomp($line = <STDIN>); #习惯用法,效果同上
while(defined($line = <STDIN>)){
print "I saw $line!";
}
上述代码意义:读取标准输入,将其存入某个变量,检查变量的值是否被定义,以及是否该执行while循环的主体(也就是还没遇到输入的结尾)。因此,我们会在循环主体内,看到$line变量里的内容。当省略变量时,简写如下:
#行输入简化写法1——省略变量时
while(<STDIN>){
#标量上下文 等效while(defined($line = <STDIN>)){
#输入多行
print "I saw $_"; #采用默认变量,等效print "I saw $line\n";
}
#行输入简化写法2——采用默认变量$_
while(defined($_ = <STDIN>)){
chomp($_);
print "I saw $_\n";
}
编译运行:
horse #键盘输入
I saw horse #输出
dog
I saw dog
shirk
I saw shirk
^Z #control+Z结束输入
钻石操作符<> 作用:
#上述多行输入的代码通过钻石操作符<>可继续简化为:
#行输入简化写法3——采用钻石操作符<>
while(defined($line = <>)){
chomp($line);
print "That I was $_ I saw!\n";
}
#行输入简化写法4——采用钻石操作符<>与$_
while(defined($_ = <>)){
chomp($_);
print "That I was $_ I saw!\n";
}
#行输入简化写法5——采用钻石操作符<> #最简化写法
while(<>){
#当无调用参数时,使用标准输入;当有调用参数时,读取文件内容
chomp; #当不加参数时,chomp会直接作用在$_上
print "That I was $_ I saw!\n";
}
while(<>){
#当无调用参数时,使用标准输入;当有调用参数时,读取文件内容
chomp; #当不加参数时,chomp会直接作用在$_上
print "That I was $_ I saw!\n";
}
编译运行:
编译命令:perl input.pl
##############不含调用参数####################
horse #键盘输入
I saw horse #输出
dog
I saw dog
shirk
I saw shirk
^Z #control+Z结束输入
编译命令:perl input.pl a.txt b.txt c.txt
##############调用参数####################
That I was a11111 I saw!
That I was a22222 I saw!
That I was a33333 I saw! #读取a.txt文件中的预先设置的三行内容
That I was b11111 I saw!
That I was b22222 I saw!
That I was b33333 I saw! #读取b.txt文件中预先设置的的三行内容
That I was c1111 I saw!
That I was c2222 I saw!
That I was c3333 I saw! #读取c.txt文件中预先设置的的三行内容
编译命令:perl input.pl a.txt b.txt - c.txt #连字符(-)参数,表示从标准输入读取输入数据
##############调用参数####################
That I was a11111 I saw!
That I was a22222 I saw!
That I was a33333 I saw! #读取a.txt文件中的预先设置的三行内容
That I was b11111 I saw!
That I was b22222 I saw!
That I was b33333 I saw! #读取b.txt文件中预先设置的的三行内容
horse #键入horse
That I was horse I saw! #输出(读取)
wolf
That I was wolf I saw!
sneak
That I was sneak I saw!
^Z
That I was c1111 I saw!
That I was c2222 I saw!
That I was c3333 I saw! #读取c.txt文件中预先设置的的三行内容
技术上讲,钻石操作符并不会去检查命令行参数,它的参数其实是来自@ARGV数组。该数组是由Perl解释器事先建立的特殊数组,其内容就是由命令行参数组成的列表,在程序运行时,@ARGV里就已经塞满了调用参数。
@ARGV = qw# b.txt - a.txt#; #预先植入了调用参数,编译命令中可以省略
while(<>){
#当有调用参数时,读取文件内容
chomp;
print "That I was $_ I saw!\n";
}
编译运行:
编译命令:perl input.pl
##############调用参数——实际上是调用@ARGV数组中的参数####################
That I was b11111 I saw!
That I was b22222 I saw!
That I was b33333 I saw!
horse
That I was horse I saw!
wolf
That I was wolf I saw!
^Z
That I was a11111 I saw!
That I was a22222 I saw!
That I was a33333 I saw!
编译命令:perl input.pl a.txt b.txt #编译命令并不会影响最终的编译结果(先b后a)
##############调用参数——实际上是调用@ARGV数组中的参数####################
That I was b11111 I saw!
That I was b22222 I saw!
That I was b33333 I saw!
horse
That I was horse I saw!
wolf
That I was wolf I saw!
^Z
That I was a11111 I saw!
That I was a22222 I saw!
That I was a33333 I saw!
use 5.010; #添加say特性
print "Hello\n"; #手工添加换行符“\n”
print "Hello\n";
print "Hello\n";
say "Hello"; #say不需要在添加换行符
say "Hello";
say "Hello";
$name = "Larry Wall";
print "Hello there, $name!\n";
say "Hello there, $name!";
编译结果:
Hello
Hello
Hello
Hello
Hello
Hello
Hello there, Larry Wall!
Hello there, Larry Wall!
print ("Hello, world\n");
print "Hello, world\n"; #括号可以省略
print (2+3); #结果5
print "\n";
print 2+3; #结果5
print "\n";
print (2+3)*4; ######糟糕,结果5######, 只要开启警告功能,perl就会找出这类问题。
print "\n";
$result = print(2+3); #结果5——加了括号就相当于函数调用,调用成功为真,$result值为1
print "\n";
$result * 4;
print $result; #结果1
print "\n";
print ((2+3)*4); #结果20——将所有的都括起来,say也可以
Perl中的格式化输出与C语言中printf用法基本一致,提供了四种格式:
#printf用法
$user = "Bill";
$days_to_die = 6;
printf "Hello, %s, your passward expires in %d days.\n",$user,$days_to_die; #%s-字符串,%d——整数
printf "in %d days.\n",17.85; #取整数:in 17 days.
printf "%6d\n",42; #指定宽度——6个字符宽度
printf "%2d\n",12345; #宽度不够——自动扩展
printf "%12.3f\n",6*7+2/3; #指定小数位宽,共12位,小数点后3位
printf "%f\n",6*7+2/3;
printf "%12f\n",6*7+2/3; #总位数12,小数
printf "%12.0f\n",6*7+2/3; #总位数12,整数,共12位,小数点后0位
编译运行:
Hello, Bill, your passward expires in 6 days.
in 17 days.
42
12345
42.667
42.666667
42.666667
43
将数组作为printf的参数:
my @items = qw(wilma dino pebbles);
my $format = "%-10s\n" x 3; #等效:"%-10s\n" x @items,标量上下文
printf $format, @items;
print "\n";
printf "%-10s\n" x @items, @items;
print "\n";
printf "%10s\n%10s\n%10s\n",@items; #默认右对齐
print "\n";
printf "%-10s\n%10s\n%-10s\n",@items; #负号-表示左对齐
编译运行:
wilma
dino
pebbles
wilma #负号-表示左对齐
dino
pebbles
wilma #默认右对齐
dino
pebbles
wilma
dino
pebbles
文件句柄就是程序里代表Perl进程与外界之间I/O联系的名称(纽带),这种联系的名称并不是文件的名称。
命名规则:须以字母、数字及下划线组成,但不能以数字开头,习惯上使用全大写字母命名文件句柄,避免和标签混淆。
特殊句柄:Perl中保留了6个特殊文件句柄:STDIN、STDOUT、STDERR、DATA、ARGV、ARGVOUT。命名句柄不应与保留字重合。
打开文件句柄:通过open操作符告诉Perl,要求操作系统为你的程序和外界架起一座桥梁。
###新版Perl 5.6之后,open的三个参数形式写法:
open MYFILE, "<", "a.txt" #小于号——表示此文件是用来读取的
open TXTFILE, ">", "d.txt" #大于号——表示如果文件存在,则清除文件原有内容并写入新内容;如果文件不存在,则创建一个新的文件,写入内容
open FILE, ">>", "d.txt" #两个大于号——表示如果文件存在,以追加的方式写入内容;如果文件不存在,就会创建一个新文件,和只有一个大于号的情形相同。
关闭文件句柄:通过close操作符关闭文件句柄,让Perl通知操作系统,我们对数据流的处理已经完成。
close FILE; #为了代码的工整性,每一个open搭配一个close。每一个句柄用完之后立刻关闭它。
有问题的文件句柄:通过die函数来触发文件处理过程中的致命错误并给出错误信息($!符号)。
#首先,如果我们一开始就用-w选项或者warnings编译指令启动警告功能,那么当遇到有问题的文件句柄时,Perl也会发出警告。
#即使不启用警告功能,open返回值同样可以告诉我们程序执行成功与否:
my $success = open FILE1, "<", "e.txt"; #文件不存在,打开文件失败
if(!$success){
print "打开文件失败\n";
}
常用简化写法——用die函数触发错误并发出错误信息(程序名与行号)。
if(!open FILE2, "<", "e.txt" ){
die "Cannot open file:$!"; #符号$!——表示“可读的系统错误信息”
}
自动检测致命错误:从Perl 5.10开始,autodie编译指令成为标准库的一部分,只需加上“use autodie”,如果open失败,它会自动启动die。
代码示例:
use autodie;
open FILE2, "<", "e.txt"
编译运行:
Can't open 'e.txt' for reading: 'No such file or directory' at handle.pl line 34
以写入或添加模式打开的文件句柄可以在print或printf函数中使用,使用时将其直接放在函数名之后、参数列表之前:
print "Hello\n";
###############读取文件#########################
if(!open MYFILE, "<", "a.txt"){
#MYFILE_文件句柄(名称随意), <_输出, 文件名
die "打开文件失败:$!";
}
while(<MYFILE>){
print $_;
}
close MYFILE; #关闭文件句柄
###############写入文件#########################
if(!open TXTFILE, ">", "b.txt"){
#>_写入文件, 若文件不存在,则创建文件
die "创建文件失败:$!";
}
print TXTFILE "Hello perl\n"; #####使用文件句柄::将该行内容写入指定文件(无逗号)
close TXTFILE;
###############追加文件#########################
if(!open FILE, ">>", "b.txt"){
#>>_表示追加内容,如同一文件在用>_则会覆盖原有内容
die "打开文件失败:$!";
}
print FILE "Hello perl against!\n"; #####使用文件句柄::要追加的内容
close FILE;
###############句柄错误的处理方法#########################
my $success = open FILE1, "<", "e.txt"; #文件不存在,打开文件失败
if(!$success){
print "\n打开文件失败\n";
}
#简化版——die用法
if(!open FILE2, "<", "e.txt"){
die "Cannot open file:$!";
}
编译运行:
Hello
a11111
a22222
a33333
打开文件失败
Cannot open file:No such file or directory at handle.pl line 34.