Perl-输入与输出1

标准输入、标准输出、标准错误
键盘为标准输入
屏幕为标准输出

1. 读取标准输入

行输入操作符<STDIN>,在标量上下文中,会返回标准输入的下一行

$line = <STDIN>;
chomp($line);

chomp($line = <STDIN>);

<STDIN>为行输入操作符,每次读取1行
当行输入操作符在读到文件末尾,没有可读内容时会返回undef,所以借此可以跳出循环

while (defines($line = <STDIN>)){
	print "I saw $line";
}

第1行代码做了很多事情:读取标准输入,将标准输入存入某个变量,检查变量的值是否被定义,判断是否该执行while循环的主体

其简写形式为

while(<STDIN>){
	print "I saw $_";
}

从标准输入读入某个变量,只要能读到内容,就进入while循环
完整形式为

while(defined($_ = <STDIN>)){
	print "I saw $_";
}

如果把行输入操作符放在其它任何地方,特别是单独成行时,它不会读取1行并存到$_。只有在while循环的条件表达式中只有行输入操作符时,才会按照这个方式运行
如果在列表上下文中调用行输入操作符,它会返回1个列表,其中包含剩余的所有输入内容

foreach(<STDIN>){
	print "I saw $_";
}

尽量用while循环

2. 来自钻石操作符的输入

一边从标准输入拿数据,一边输出结果到标准输出

$ ./my_program fred barney betty # 执行当前目录下的my_program命令,让它依次处理文件fred、barney和betty

上面的例子中,命令行的参数就是要依次处理的几个文件的名字
如果不提供任何调用参数,程序会从标准输入流采集数据。
如果参数是连字符(-),则表示从标准输入读取数据
假如调用参数是 fred - betty,程序先处理文件fred,然后处理标准输入流中提供的数据,最后才是文件betty

好处:可以在运行时指定程序的输入源,不需要重写程序,就可以通过管道(pipeline)的方式递送数据,把上游的数据递交给这个程序处理

钻石操作符是行输入符的特例,但钻石操作符不是从键盘取得输入,而是从用户指定的位置读取

while (defined($line = <>)){
	chomp($line);
	print "It was $line that I saw!\n";
}

使用钻石操作符时,好像这些文件已经合并成1个很大的文件一样
钻石操作符只有在碰到所有输入的结尾时才会返回undef(然后我们的程序就会跳出while循环)

while(<>){
	chomp;
	print "It was $_ that I saw!\n";
}

由于钻石操作符通常会处理所有的输入,所以一旦看到钻石操作符出现在程序中多处时,通常都是错误的
钻石操作符是用来读取输入的,而输入的内容可以在$_中使用
can't open wilma: No such file or driectory

3. 双钻石操作符

钻石操作符存在1个问题:如果命令行上传入的文件名带有特殊字符,比如|(管道符),就会引发管道操作
双钻操作符 <<>>,功能与钻石操作符相同,但是不再启动外部程序

use v5.22;

while(<<>>){
	chomp;
	print "It was $_ that I saw!\n";
}

4. 调用参数

钻石操作符不会检查命令参数,它看到的是放在@ARGV数组里面的数据

如果需要的命令行选项不止一两个,最好用标准模块实现
Getopt::Long和Getopt::Std

钻石操作符会查看数组@ARGV,然后决定该用哪些文件名,如果钻石操作符找到的是空列表,就会改用标准输入流,否则,就会使用@ARGV里的文件列表

@ARGV = qw # larry moe curly #; # 强制让钻石操作符只读取这3个文件
while(<>){
	chomp;
	print "It was $_ that I saw in some stooge-like file!\n";
}

5. 输出到标准输出

print操作符会读取它后面的参数列表中的所有元素,并把每一项(当然是1个字符串)依次送到标准输出

$name = "Larry Wall";
print "Hello there, $name, did you know that 3+4 is ", 3+4, "?\n";

直接使用数组和使用数组内插在打印效果上是不同的

print @array; # 一个接一个地把数组中的所有元素打印出来,元素之间不会有空格
print "@array"; # 只打印出来1个字符串(数组元素内插的结果),数组@array内所有元素用空格分隔后合成的字符串

perl把数组内插到字符串中时,会在元素之间加上空格,空格实际上是特殊变量$"定义的内容,默认是空格字符
一般在使用引号的场合,字符串后面都最好加上\n

由于print处理的是待打印的字符串列表,因此它的参数会在列表上下文中被执行,可以配合钻石操作符

print <>; # 相当于unix下的/bin/cat命令
print sort <>; #相当于unix下的/bin/sort命令

假如print调用看起来像函数调用,那它就是一个函数调用
调用函数时,函数名后面必须紧接着一对括号,包含调用函数的参数

print (2+3);

print (2+3)*4; # 丢弃返回值1,而不是打印20

没有括号时,print是列表操作符,会把其后列表里的所有东西全都输出来
print后面紧跟着左括号时,print就是1个函数调用,只会把括号内的东西输出来

6. 用printf格式化输出

printf操作符的参数包括

  1. 格式字符串(模板)
  2. 要输出的数据列表
printf "Hello, %s; your passward expires in %d days!\n", $user, $days_to_die;

格式字符串里可以有多个转换,每种转换都会以百分比符号(%)开头,然后以某个字母结尾,而后面的列表里的元素的个数应该和转换的数目一样多

  1. %g,以恰当的形式输出某个数字,%g会按需要自动输出浮点数、整数、甚至指数形式
  2. %d,十进制数字,舍去小数点后的数字,无条件截断,而非四舍五入
  3. %x,十六进制数字
  4. %o,八进制数字
  5. %s,字符串格式,字符串内插,支持设定字段宽度
  6. %f,浮点数转换格式,可按需四舍五入,可指定小数点后的位数
  7. %%,输出真正的百分号
printf "%g %g %g\n", 5/2, 51/17, 51**17; # 2.5 3 1.0683e+29

printf "in %d days!\n", 17.85; # in 17 days!

printf "in %x days!\n", 17; # in 0x11 days!

printf "in %o days!\n", 17; # in 021 days!

printf "%6d\n", 42; # ````42

printf "%2d\n", 2e3 + 1.95; # 2001

printf "%10s\n", "wilma"; # `````wilma

printf "%-15s\n", "flintstone"; # flintstone`````

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

printf "Monthly interest rate: %.2f%%\n", 5.25/12; # "Monthly interest rate: 0.44%"

printf "%*s", 10, "Wilma"; # `````wilma

printf "%*.*f", 6, 2, 3.1415926; # ```3.14
printf "%*.*f", 6, 3, 3.1415926; # ``3.142
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值