table {
border-collapse: collapse;
width: 100%;
margin-bottom: 1rem;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
pre {
background-color: #f8f8f8;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
}
1、编写并运行一个输出“Hello, world”的Perl程序。
实现 “Hello, world” 程序的方式
可使用以下几种方式实现 “Hello, world” 程序:
1. 编写文件
创建一个 Perl 文件,内容为:
perl
print "Hello, world!
";
保存后在命令行运行:
perl 文件名
若使用 v5.10 或更高版本,可写为:
perl
use v5.10;
say "Hello, world!";
2. 命令行运行
使用
-e
开关:
$ perl -e 'print "Hello, World
"'
使用
-l
开关自动添加换行符:
$ perl -le 'print "Hello, World"'
在 Windows 的
command.exe
(或
cmd.exe
)中,使用双引号在外:
C:> perl -le "print 'Hello, World'"
也可使用广义引号:
C:> perl -le "print q(Hello, World)"
v5.10 及更高版本使用
-E
开关启用新特性,可使用
say
。
2、编写一个程序,计算半径为 12.5 的圆的周长。圆的周长是 2π 乘以半径(约为 2 乘以 3.141592654)。你得到的答案应该约为 78.5。
#!/usr/bin/perl
use warnings;
$pi = 3.141592654;
$radius = 12.5;
$circ = 2 * $pi * $radius;
print "The circumference of a circle of radius $radius is $circ.
";
3、编写一个程序,提示用户输入一个圆的半径,然后根据输入的半径计算并输出该圆的周长。例如,如果用户输入的半径为 12.5,程序应计算并输出该半径对应的圆的周长。
#!/usr/bin/perl
use warnings;
$pi = 3.141592654;
print "What is the radius? ";
chomp($radius = <STDIN>);
$circ = 2 * $pi * $radius;
print "The circumference of a circle of radius $radius is $circ.
";
4、编写一个程序,提示用户输入两个数字(分别在不同的输入行),并输出这两个数字相乘的结果。
以下是实现该功能的程序:
print "Enter first number: ";
chomp($one = <STDIN>);
print "Enter second number: ";
chomp($two = <STDIN>);
$result = $one * $two;
print "The result is $result.
";
5、编写一个程序,提示用户输入一个字符串和一个数字(分别在不同的输入行),然后将该字符串按照数字指定的次数逐行输出。(提示:使用 x 运算符)。如果用户输入“fred”和“3”,输出应该是三行,每行都显示“fred”。如果用户输入“fred”和“299792”,可能会有大量输出。
以下是实现该功能的 Perl 代码示例:
print "请输入一个字符串: ";
my $string = <STDIN>;
chomp $string; # 去除换行符
print "请输入一个数字: ";
my $number = <STDIN>;
chomp $number; # 去除换行符
print ($string . "
") x $number;
这段代码首先提示用户输入一个字符串和一个数字,然后使用
x
运算符将字符串重复指定的次数,并逐行输出。
6、编写一个程序,逐行读取一系列数字,直到输入结束。然后,对于每个输入的数字,从以下列表中打印出对应的人名(将此人名列表硬编码到程序中,即该列表应出现在程序的源代码中)。例如,如果输入的数字是1、2、4和2,输出的人名将是fred、betty、dino和betty。人名列表为:fred betty barney dino wilma pebbles bamm – bamm
以下是一个用Python实现的示例代码:
names = ['fred', 'betty', 'barney', 'dino', 'wilma', 'pebbles', 'bamm - bamm']
while True:
try:
num = int(input())
if 1 <= num <= len(names):
print(names[num - 1])
else:
print('输入的数字超出范围')
except EOFError:
break
这段代码首先定义了人名列表,然后通过循环不断读取输入的数字,将数字转换为对应列表索引并打印出人名,直到遇到输入结束符。
7、编写一个名为 total 的子例程,它返回一个数字列表的总和。提示:该子例程不应执行任何输入/输出操作;它应仅处理其参数并将值返回给调用者。在这个示例程序中测试它,该程序只是测试子例程以查看其是否正常工作。第一组数字的总和应该是 25。代码如下:my @fred = qw{ 1 3 5 7 9 }; my $fred_total = total(@fred); print “The total of @fred is $fred_total.
”; print “Enter some numbers on separate lines: “; my $user_total = total(
); print “The total of those numbers is $user_total.
”; 注意,像这样在列表上下文中使用
将等待你以适合你系统的任何方式结束输入。
以下是实现该功能的代码:
sub total {
my $sum = 0;
foreach (@_) {
$sum += $_;
}
return $sum;
}
该子例程使用
$sum
来保存总和,通过
foreach
循环遍历参数列表并累加每个参数,最后返回总和。为避免返回值可能为未定义,将
$sum
初始化为
0
。
8、编写一个名为 above_average 的子程序,它接受一个数字列表,并返回那些高于平均值(均值)的数字。(提示:编写另一个子程序,通过将总和除以项目数量来计算平均值。)在以下测试程序中测试你的子程序:my @fred = above_average(1..10); print “@fred is @fred
”; print “(Should be 6 7 8 9 10)
”; my @barney = above_average(100, 1..10);
以下是实现上述功能的代码:
sub total {
my $sum = 0;
foreach my $num (@_) {
$sum += $num;
}
return $sum;
}
sub average {
if (@_ == 0) { return }
my $count = @_;
my $sum = total(@_);
return $sum/$count;
}
sub above_average {
my $average = average(@_);
my @list;
foreach my $element (@_) {
if ($element > $average) {
push @list, $element;
}
}
return @list;
}
my @fred = above_average(1..10);
print "@fred is @fred
";
print "(Should be 6 7 8 9 10)
";
my @barney = above_average(100, 1..10);
print "@barney is @barney
";
在上述代码中,
total
子程序用于计算数字列表的总和,
average
子程序用于计算平均值,
above_average
子程序用于返回高于平均值的数字列表。最后进行了测试调用。
9、编写一个名为 greet 的子程序,该子程序在欢迎你指定的人时,告知他们上一个被问候的人的名字。执行语句序列 greet( “Fred” ); greet( “Barney” ); 时,应输出:Hi Fred! You are the first one here! Hi Barney! Fred is also here!
use v5.10;
sub greet {
state $last_person;
my $name = shift;
print "Hi $name! ";
if ( defined $last_person ) {
print "$last_person is also here!
";
} else {
print "You are the first one here!
";
}
$last_person = $name;
}
greet( 'Fred' );
greet( 'Barney' );
10、修改程序,使得当执行语句序列:greet( “Fred” ); greet( “Barney” ); greet( “Wilma” ); greet( “Betty” ); 时,能输出:Hi Fred! You are the first one here! Hi Barney! I’ve seen: Fred Hi Wilma! I’ve seen: Fred Barney Hi Betty! I’ve seen: Fred Barney Wilma 。
以下是修改后的程序:
use v5.10;
greet( 'Fred' );
greet( 'Barney' );
greet( 'Wilma' );
greet( 'Betty' );
sub greet {
state @names;
my $name = shift;
print "Hi $name! ";
if( @names ) {
print "I've seen: @names";
} else {
print "You are the first one here!";
}
push @names, $name;
}
11、编写一个程序,要求用户在不同行输入一系列字符串,将每个字符串右对齐打印在一个20字符宽的列中。为确保输出列位置正确,同时打印一行数字作为“标尺线”(仅用于调试)。要确保不会误使用19字符宽的列。例如,输入“hello”和“good – bye”,输出应类似这样:123456789012345678901234567890123456789012345678901234567890
hello
good – bye
以下是实现该功能的Perl程序:
print "Enter some lines, then press Ctrl - D:
"; # or Ctrl - Z
chomp(my @lines = <STDIN>);
print "1234567890" x 7, "12345
"; # ruler line to column 75
foreach (@lines) {
printf "%20s
", $_;
}
该程序首先提示用户输入一些行,然后按Ctrl – D(或Ctrl – Z)结束输入。接着读取并去除每行输入末尾的换行符。之后打印标尺线,最后通过循环将每行字符串右对齐打印在20字符宽的列中。
12、修改之前的程序,让用户选择列宽,这样依次输入 30、hello、good – bye(分行输入)时,字符串会显示在第 30 列。额外加分项:当所选宽度较大时,让标尺行更长。
以下是实现该功能的代码:
print "What column width would you like? ";
chomp(my $width = <STDIN>);
print "Enter some lines, then press Ctrl - D:
"; # or Ctrl - Z
chomp(my @lines = <STDIN>);
print "1234567890" x (($width+9)/10), "
"; # ruler line as needed
foreach (@lines) {
printf "%${width}s
", $_;
}
或者使用另一种方式:
foreach (@lines) {
printf "%*s
", $width, $_;
}
13、编写一个程序,要求用户输入一个名字,并根据以下名字和姓氏的对应关系输出对应的姓氏:弗雷德对应弗林斯通,巴尼对应鲁布尔,威尔玛对应弗林斯通。
以下是一个满足需求的 Perl 程序示例:
use v5.10;
# 定义名字和姓氏的映射
my %name_map = (
'fred' => 'flintstone',
'barney' => 'rubble',
'wilma' => 'flintstone'
);
# 提示用户输入名字
print "请输入一个名字: ";
chomp(my $given_name = <STDIN>);
$given_name = lc $given_name; # 转换为小写以匹配映射
# 检查输入的名字是否在映射中
if (exists $name_map{$given_name}) {
print "对应的姓氏是: $name_map{$given_name}
";
} else {
print "未找到对应的姓氏。
";
}
这个程序首先定义了一个哈希表
%name_map
来存储名字和姓氏的映射。然后提示用户输入一个名字,将输入转换为小写以匹配映射。最后,检查输入的名字是否在映射中,如果是,则输出对应的姓氏;否则,输出未找到对应的姓氏的提示。
14、编写一个程序,逐行读取一系列单词,直到输入结束,然后输出每个单词出现的次数。例如,如果输入的单词是 fred、barney、fred、dino、wilma、fred(每行一个单词),输出应显示 fred 出现了 3 次。额外加分项:按代码点顺序对输出的单词进行排序。
以下是实现该功能的 Perl 代码:
my(@words, %count, $word);
chomp(@words = <STDIN>);
foreach $word (@words) {
$count{$word} += 1;
}
foreach $word (sort keys %count) {
print "$word was seen $count{$word} times.
";
}
代码解释:
首先声明变量,使用
<STDIN>
读取所有输入行到
@words
数组并去除换行符。第一个
foreach
循环遍历所有单词,将每个单词作为键,其出现次数作为值存储在
%count
哈希表中。第二个
foreach
循环按代码点顺序遍历哈希表的键,并输出每个单词及其出现次数。
15、编写一个程序,打印输入中提及“fred”的每一行,对其他行不做处理。判断输入字符串为“Fred”、“frederick”或“Alfred”时是否匹配。创建一个包含几行提及“fred flintstone”及其朋友的小文本文件,然后将该文件作为此程序的输入。
要实现该程序,可以使用正则表达式匹配
fred
。示例代码如下:
while (<>) {
if (/fred/) {
print;
}
}
此程序只会匹配精确的
fred
,输入
Fred
、
frederick
或
Alfred
时不匹配。可创建一个小文本文件,将其作为输入运行此程序。
16、修改一个程序,使其能匹配“Fred”。若输入字符串是“Fred”、“frederick”或“Alfred”,判断修改后的程序是否能匹配这些字符串,并在文本文件中添加包含这些名字的行。
可将程序中的模式改为
/[fF]red/
,也可以尝试
/(f|F)red/
或
/fred|Fred/
,但字符类更高效。修改后,“Fred”能匹配,“frederick”和“Alfred”也能匹配,因为当前没有限定只匹配完整单词,后续会介绍相关功能来解决这个问题。
17、编写一个程序,打印出任何同时提及“wilma”和“fred”的输入行。
可使用正则表达式和循环遍历输入行,若一行同时包含“wilma”和“fred”则打印该行。示例代码(Python):
while True:
try:
line = input()
if 'wilma' in line.lower() and 'fred' in line.lower():
print(line)
except EOFError:
break
18、编写一个程序,该程序会反复要求用户猜测一个1到100之间的秘密数字,直到用户猜对为止。程序应使用神奇公式 int(1 + rand 100) 随机选取这个数字。当用户猜错时,程序应回应“Too high”或“Too low”。如果用户输入“quit”或“exit”,或者输入空行,程序应退出。当然,如果用户猜对了,程序也应退出!
以下是实现该功能的Perl代码:
my $secret = int(1 + rand 100);
while (1) {
print "Please enter a guess from 1 to 100: ";
chomp(my $guess = <STDIN>);
if ($guess =~ /quit|exit|As*z/i) {
print "Sorry you gave up. The number was $secret.
";
last;
} elsif ($guess < $secret) {
print "Too low. Try again!
";
} elsif ($guess == $secret) {
print "That was it!
";
last;
} else {
print "Too high. Try again!
";
}
}
19、修改一个程序,使其在运行过程中打印额外的调试信息,例如它选择的秘密数字。进行修改,以便可以关闭此功能,并且在关闭时程序不会发出警告。如果你使用的是 Perl 5.10 或更高版本,请使用 // 运算符。否则,请使用条件运算符。
下面是给定的【文本内容】:
使用 Perl 5.10 或更高版本:
```perl
use v5.10;
my $Debug = $ENV{DEBUG} // 1;
my $secret = int(1 + rand 100);
print "Don't tell anyone, but the secret number is $secret.
" if $Debug;
不使用 Perl 5.10 或更高版本:
my $Debug = defined $ENV{DEBUG} ? $ENV{DEBUG} : 1;
my $secret = int(1 + rand 100);
print "Don't tell anyone, but the secret number is $secret.
" if $Debug;
##20、编写一个程序,找出命令行中指定的最旧文件并报告其存在天数。如果文件列表为空(即命令行中未提及任何文件),程序会怎样处理?
程序会直接报错,输出 `'No file names supplied!'` 并终止运行,因为没有文件可供检查,也就不存在最旧的文件。
##21、编写一个程序,使用堆叠文件测试运算符列出命令行中指定的所有可读、可写且归当前用户所有的文件。
以下是一个使用 Perl 语言实现的示例程序,该程序使用堆叠文件测试运算符列出命令行中指定的所有可读、可写且归当前用户所有的文件:
```perl
#!/usr/bin/perl
use v5.10;
foreach my $filename (@ARGV) {
if (-r -w -o $filename) {
print "$filename 是可读、可写且归你所有的文件。
";
}
}
将上述代码保存为一个
.pl
文件,例如
file_test.pl
,然后在命令行中运行该程序并传入文件名作为参数,程序将输出所有满足条件的文件。例如:
perl file_test.pl file1.txt file2.txt
22、编写一个程序,向用户询问一个目录名,然后切换到该目录。如果用户输入的行只有空白字符,则默认切换到他或她的主目录。切换后,按字母顺序列出普通目录内容(不以点开头的项目)。如果目录切换不成功,只需提醒用户,但不要尝试显示内容。
以下是实现该功能的程序:
print "Which directory? (Default is your home directory) ";
chomp(my $dir = <STDIN>);
if ($dir =~ /As*z/) { # A blank line
chdir or die "Can't chdir to your home directory: $!";
} else {
chdir $dir or die "Can't chdir to '$dir': $!";
}
my @files = <*>;
foreach (sort @files) {
print "$_
";
}
该程序首先提示用户输入目录名并去除换行符。若输入为空,则切换到主目录;否则,切换到用户指定的目录。切换成功后,使用通配符
<*>
获取目录中的普通文件和文件夹(不包含以点开头的隐藏文件),并按字母顺序排序后逐个打印。若切换目录失败,程序会输出错误信息并终止。
23、编写一个程序,其功能类似于
rm
命令,删除命令行中指定的所有文件。(你不需要处理
rm
命令的任何选项。)
rm
rm
在 Perl 中,可以使用
unlink
操作符来实现该功能。示例代码如下:
unlink @ARGV;
my $successful = unlink @ARGV;
print "I deleted $successful file(s) just now
";
上述代码中,
@ARGV
数组包含了命令行上提供的所有参数,也就是要删除的文件名列表。使用
unlink
操作符删除这些文件,并通过
$successful
变量来检查成功删除的文件数量。
如果需要详细了解每个文件的删除情况,可以按如下方式逐个删除文件:
foreach my $file (@ARGV) {
unlink $file or warn "failed on $file: $!
";
}