Perl的print系列函数使用参考
2017-10-07 22:23:31 阿炯

Perl中的向终端或文件句柄中输出的基本函数,本文涵盖如下三个函数:print、printf、sprintf

详细用法可以查看perl用户手册:
perldoc -f print
perldoc -f printf
perldoc -f sprintf

他们各自支持的命令格式,都有三四种,但是常用的也就一两种。

print 函数
打印表达式中列表​值到当前默认的输出文件句柄。

语法
print FILEHANDLE LIST
print LIST
print

定义和用法
打印表达式中列表值到当前默认的输出文件句柄,或到一个指定的文件句柄。
如果设置,则将$\变量添加到列表LIST 的末尾。
如果列表LIST是空的,$_的值将被打印代替。
打印接受列表的值,列表中的每一个元素将被解释为一个表达式。

返回值
0 - 失败
1 - 成功

printf 函数
将列表LIST的值通过指定的格式打印到当前输出文件句柄,或一个指定的文件句柄。

语法
printf FILEHANDLE FORMAT,LIST
printf FORMAT,LIST

定义和用法
打印解释,通过指定的格式格式到当前输出文件句柄值的列表LIST,或一个指定的文件句柄。

实际上相当于打印FILEHANDLE的sprintf(FORMAT,LIST)

可以使用printf打印的情况:如果并不需要一个特定的输出格式。printf函数先格式化字符串再输出到指定文件或当前缺省文件中,如:
printf OUTFILE (“You owe me %8.2f",$owing);

此语句取出变量$owing的值并替换掉串中的%8.2f,%8.2f是域格式的例子,把$owing的值看作浮点数。

以下是公认的格式转换。
Format     Result
%%     A percent sign
%c     A character with the given ASCII code
%s     A string
%d     A signed integer (decimal)
%u     An unsigned integer (decimal)
%o     An unsigned integer (octal)
%x     An unsigned integer (hexadecimal)
%X     An unsigned integer (hexadecimal using uppercase characters)
%e     A floating point number (scientific notation)
%E     A floating point number, uses E instead of e
%f     A floating point number (fixed decimal notation)
%g     A floating point number (%e or %f notation according to value size)
%G     A floating point number (as %g, but using .E. in place of .e. when appropriate)
%p     A pointer (prints the memory address of the value in hexadecimal)
%n     Stores the number of characters output so far into the next variable in the parameter list

Perl也支持,有选择地调整输出格式的标志,这些被指定%和转换字母。它们显示在下面的表中:
Flag     Result
space     Prefix positive number with a space
+     Prefix positive number with a plus sign
-     Left-justify within field
0     Use zeros, not spaces, to right-justify
#     Prefix non-zero octal with .0. and hexadecimal with .0x.
number     Minimum field width
.number     Specify precision (number of digits after decimal point) for floating point numbers
l     Interpret integer as C-type .long. or .unsigned long.
h     Interpret integer as C-type .short. or .unsigned short.
V     Interpret integer as Perl.s standard integer type
v     Interpret the string as a series of integers and output as numbers separated by periods or by an arbitrary string extracted from the argument when the flag is preceded by *.

printf函数有一个模板,叫格式字符串,它可以规定输出的格式,每个格式符有百分号开头,由字母结束。格式化字符串中有3个格式符,则对应3个元素。
%g 输出数字,它将根据需要自动选用浮点数,整数或者指数
%d 十进制整数,%x 十六进制,%o八进制,根据需要截尾;无条件截断(非四舍五入)
%f or %s 限制宽度 其中正数是右对齐,负数是左对齐
%s 是针对字符串的,如%10s, %-15s
%f 针对数字的,如%12.3f (表示输出共12个字符,包括小数点,并且小数点后面只有3位数)
%% 输出百分号,不会使用后面列表中的元素

printf的显示位宽度也可以作为参数来另外指定:先在格式字符串中用'*'占位,接下来第一个参数是宽度,第二个是字符串内容:
printf "%*s",9,'FreeOA';    #前置空格

也可以用两个'*'表示浮点数的总宽度和小数部分的宽度:
use constant PI => 4 * atan2(1, 1);
printf "%*.*f",7,2,PI;


返回值
0 - 失败
1 - 成功

示例
打印数组的第1,2字段值:
printf "%-50s%-20s\n",$arr[0],$arr[1];

my @a=qw(FreeOA good-bye);
printf"".("%20s\n" x @a) ,@a;
(printf"%20s\n,%20s\n",@a;)  #:printf输出格式只是针对一个元素,所以想输出所有元素的格式,就要输出所有的形式,或者用“x”这个来完成。

sprintf() 函数
在LIST的值的基础上返回一个格式化字符串。

语法
sprintf FORMAT,LIST

定义和用法
返回一个格式化字符串在LIST的值的基础上。 本质上等同于printf,但格式的字符串返回,而不是被打印。

返回值
SCALAR,一个格式化的文本字符串。

$text = sprintf("%0d\n", 9);
print "Formated string is $text\n";

结果:
Formated string is 9

$result = sprintf('The %s is %d', 'answer', 42);

my @items = qw(wilma dino freeoa pebbles);
my $format = "The items are:\n" . ("%10s\n" x @items);
# print "the format is <<$format>>\n";for debugging
printf $format, @items;


三者的区别
command  description
print  打印信息,可以输出到文件里
printf  可以整理信息的格式,可以输出到文件里。与sprintf类似,区别是可以打印
sprintf  可以整理信息的格式。与printf类似,区别是仅仅用于字符串的格式化,没有任何print效果。

另加对say的解析

print、printf和say都可以输出信息。print和say类似,print不自带换行符,say自带换行符,但要使用say,Perl版本必须在5.10之上:'use 5.010;',printf像C语言的printf一样,可以定制输出格式。它们有返回值:如果输出成功,就返回1。另外注意perl中有上下文的概念,这几个输出操作也同样有上下文环境:列表上下文。
@arr=qw(hello world);
print "hello world","\n";
print "hello world\n";  
print @arr;    # 输出helloworld(没空格)
print "@arr";    # 输出hello world(有空格)

print/say可以以函数格式(print(args)/say(args))进行输出,这时候有个陷阱需要注意;示例如下:
print(3+4)*4;

这个返回7,而不是28。这是如何计算的?

Perl中很多时候是可以省略括号的,这往往让人忘记括号的归属。而Perl中又有上下文的概念,在不同上下文执行同一个操作的结果是不一样的。在这里:
1.print不加括号的时候,它需求的参数是一个列表上下文,它后面的所有内容都会被print输出;
2.print加括号的时候,它只会输出括号中的内容。

所以上面的语句等价于:(print(3+4))*4

它先执行print(7),然后拿到print的返回值1,将其乘以4,由于没有赋值给其它变量,所以这个乘法的结果被丢弃。如果将上面赋值给一个变量:
$num = print(3+4)*4;
则$num的值将为4。

如果想要输出(3+4)*4=28的结果,可以将它们放在一个括号里,或者在(3+4)的括号前加一个+号,它表示让它后面的表达式作为函数的参数,相当于加个括号。所以下面两个是等价的语句:
print ((3+4)*4);
print +(3+4)*4;

另外由于print/say不使用括号的时候,它们会输出其后面的列表。所以有以下技巧:
1.像cat命令一样,直接输出文件内容:print <>;
2.像sort命令一样,排序文件内容:print sort <>;


参考文档
print
printf
sprintf
Using (s)printf()