关于chomp的澄清

时间:2011-09-03 00:45:32

标签: perl chomp

我现在正在上课,决定花时间学习Perl。我正在使用Beginning Perl(http://www.perl.org/books/beginning-perl/),我将在第三章结束时完成练习。

其中一个练习要求我“将您的重要电话号码存储在哈希中。编写程序以按人名查找数字。”

无论如何,我想出了这个:

#!/usr/bin/perl
use warnings;
use strict;

my %name_number=
(
Me => "XXX XXX XXXX",
Home => "YYY YYY YYYY",
Emergency => "ZZZ ZZZ ZZZZ",
Lookup => "411"
);

print "Enter the name of who you want to call (Me, Home, Emergency, Lookup)", "\n";
my $input = <STDIN>;
print "$input can be reached at $name_number{$input}\n";

它就行不通了。我不断收到此错误消息:

  

在串联(。)中使用未初始化的值或在hello.plx中使用字符串   第17行,第1行

我尝试了更多的代码,但每个“解决方案”看起来比之前的“解决方案”更复杂。最后,我决定检查答案。

我的代码和答案之间的唯一区别是在chomp ($input);之后存在<STDIN>;

现在,作者在前面的示例中使用了chomp,但他并没有真正涵盖chomp正在做的事情。所以,我在www.perlmeme.org上找到了这个答案:

  

chomp()函数将删除(通常)任何换行符   一个字符串的结尾。我们通常说的原因是它实际上   删除与$/的当前值匹配的任何字符(输入   记录分隔符),$/默认为换行符..


无论如何,我的问题是:

  1. 哪些换行符被删除? Perl是否会自动将"\n"附加到<STDIN>的输入中?我只是有点不清楚,因为当我读到“它实际上删除了与$/的当前值相匹配的任何字符时,我忍不住想”我不记得放$/在我的代码中的任何地方。“

  2. 我希望尽快制定最佳做法 - 最好是在chomp之后始终包含<STDIN>,还是有不必要的情况?

5 个答案:

答案 0 :(得分:9)

<STDIN>读到输入字符串的末尾,如果你按回车键输入它,你可能会这样做。

chomp删除字符串末尾的换行符。 $/是一个变量(如您所见,默认为换行符),您可能不必担心;它只是告诉perl'输入记录分隔符'是什么,我假设它意味着它定义了<FILEHANDLE>读取的距离。你现在几乎可以忘记它,它似乎是一个高级主题。只是假装chomp扼杀一个尾随换行符。老实说,我以前从未听说过$/

至于你的另一个问题,通常更清楚的是总是选择变量并在以后根据需要添加换行符,因为你并不总是知道变量是否有换行符;通过总是扼杀变量,你总是得到相同的行为。在某些情况下,这是不必要的,但如果您不确定它不会对chomp造成伤害。

希望这有帮助!

答案 1 :(得分:3)

好的,从1开始,perl不会在输入处添加任何\n。完成输入数字后,按 Enter 。如果您未指定$/,则将放置默认值\n(至少在UNIX下)。

从2开始),只要输入来自用户,或者只要你想删除行结束字符(例如从文件中读取),就需要chomp。

最后,您获得的错误可能来自perl,而不是在最后print的双引号内理解您的变量,因为它确实有_个字符。尝试按如下方式编写字符串:

print "$input can be reached at ${name_number{$input}}\n";

(注意最后一个变量周围的{}。)

答案 2 :(得分:2)

<STDIN>readline( *STDIN );的快捷符号。 readline()所做的是读取文件句柄,直到遇到$ /(又名$ INPUT_RECORD_SEPARATOR)的内容并返回它已读取的所有内容,包括$ /的内容。 chomp()执行的操作是删除$ /的最后一次出现内容(如果存在)。

内容通常称为换行符,但可能由多个字符组成。在Linux上,它包含一个LF字符,但在Windows上,它包含CR-LF。

请参阅:

perldoc -f readline
perldoc -f chomp
perldoc perlvar and search for /\$INPUT_RECORD_SEPARATOR/

答案 3 :(得分:0)

我认为这里的最佳做法是写:

chomp(my $input = <STDIN>);

以下是chomp函数($/含义在那里解释)的快速示例,只删除一个尾随的新行(如果有的话):

chomp (my $input = "Me\n"); # OK
chomp ($input = "Me"); # OK (nothing done)
chomp ($input = "Me\n\n"); # $input now is "Me\n";
chomp ($input); # finally "Me"

print "$input can be reached at $name_number{$input}\n"; 
顺便说一句:有趣的是,我也在学习Perl,五分钟前我就到了哈希。

答案 4 :(得分:0)

虽然可能很明显,但仍然值得一提为什么这里需要chomp

创建的哈希包含4个查找键:"Me""Home""Emergency""Lookup"

$input指定<STDIN>后,它将包含"Me\n""Me\r\n"或其他一些行结尾变体,具体取决于正在使用的操作系统。< / p>

出现未初始化的值错误,因为哈希中不存在"Me\n"键。这就是为什么需要chomp

my $input = <STDIN>; # "Me\n" --> Key DNE, $name_number{$input} not defined
chomp $input;        # "Me"   --> Key exists, $name_number{$input} defined