(六)输入与输出(<STDIN>与钻石操作符输入、@ARGV参数调用、say与printf标准输出、文件句柄使用(open/close/die)等)

文章目录

  • 一、读取输入
    • 1.1、读取标准输入
    • 1.2、通过钻石操作符输入
    • 1.3、调用参数@ARGV输入
  • 二、输出
    • 2.1、print(say)标准输出
    • 2.2、printf格式化输出——%s、%d、%f、%g
    • 2.3、printf与数组
  • 三、文件句柄
    • 3.1、打开/关闭文件句柄
    • 3.2、die处理文件错误
    • 3.3、使用文件句柄——代码示例

一、读取输入

1.1、读取标准输入

  • 读取标准输入(一行):通过行输入操作符 实现,习惯性用法:
$line = <STDIN>;                       #读取下一行
chomp($line);                          #去掉最后的换行符

chomp($line = <STDIN>);                #习惯用法,效果同上
  • 读取标准输入(多行):通过while循环与操作符结合来实现,用法如下:
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结束输入

1.2、通过钻石操作符输入

钻石操作符<> 作用:

  1. 读取键盘输入,属于行输入操作符的特例;输入可以是键盘,也可以是其它设备。
#上述多行输入的代码通过钻石操作符<>可继续简化为:
#行输入简化写法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";
}
  1. 文件处理读取文件中的内容
      使用钻石操作符<>, 在编译命令中,当无调用参数时,使用标准输入(如下例):当有调用参数时,读取文件内容
      当连字符(-)作为参数时,表示从标准输入读取输入数据
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文件中预先设置的的三行内容

1.3、调用参数@ARGV输入

  技术上讲,钻石操作符并不会去检查命令行参数,它的参数其实是来自@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!

二、输出

2.1、print(say)标准输出

  • print与say的区别:print可以改用say,效果相同,但是say不用输入换行符关键字say版本5.010中的新特性
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后的括号问题:多数情况下括号可以省略,但是并不绝对。
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也可以

2.2、printf格式化输出——%s、%d、%f、%g

  Perl中的格式化输出与C语言中printf用法基本一致,提供了四种格式:

  1. %d:表示输出十进制整数,它会舍去小数点后的数字,可设定字段宽度;
  2. %s:表示输出字符串格式,功能其实就是字符串内插,可设定字段宽度;
  3. %f:表示按四舍五入输出浮点数,可指定字段位宽与小数点之后的输出位宽;
  4. %g:表示输出恰当的数字形式,按照需要自动输出浮点数、整数或者是指数形式。
#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

2.3、printf与数组

  将数组作为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。命名句柄不应与保留字重合。

3.1、打开/关闭文件句柄

  打开文件句柄:通过open操作符告诉Perl,要求操作系统为你的程序和外界架起一座桥梁。

###新版Perl 5.6之后,open的三个参数形式写法:

open MYFILE, "<", "a.txt"            #小于号——表示此文件是用来读取的
open TXTFILE, ">", "d.txt"           #大于号——表示如果文件存在,则清除文件原有内容并写入新内容;如果文件不存在,则创建一个新的文件,写入内容
open FILE, ">>", "d.txt"             #两个大于号——表示如果文件存在,以追加的方式写入内容;如果文件不存在,就会创建一个新文件,和只有一个大于号的情形相同。

  关闭文件句柄:通过close操作符关闭文件句柄,让Perl通知操作系统,我们对数据流的处理已经完成。

close FILE;                          #为了代码的工整性,每一个open搭配一个close。每一个句柄用完之后立刻关闭它。

3.2、die处理文件错误

  有问题的文件句柄:通过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

3.3、使用文件句柄——代码示例

  以写入或添加模式打开的文件句柄可以在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.

文件:a.txt b.txt
(六)输入与输出(<STDIN>与钻石操作符输入、@ARGV参数调用、say与printf标准输出、文件句柄使用(open/close/die)等)_第1张图片

你可能感兴趣的:(Perl学习)