我的@array 不会停止接受标准输入...
my @array = undef;
while (@array = undef){
@array = <STDIN>;
for (@array[x]=5){
@array = defined;
}
}
my @array = undef;
while (@array = undef){
这两行没有做(我假设)你认为他们正在做的事情。
my @array = undef;
这定义了一个具有单个元素的数组,该元素是特殊值undef
。我怀疑你真正想要的是:
my @array = ();
这会创建一个空数组。但是 Perl 数组在第一次创建时总是空的,所以可以简化为:
my @array;
第二行重复该错误并添加一个新错误。
while (@array = undef) {
我怀疑您想在这里检查一个空数组,并且您正在寻找类似“if”的东西@array is undefined
。但是您错过了这样一个事实,即在 Perl 中,赋值运算符(如=
)与比较运算符(如==
)不同。所以这个line分配 undef
给@array
而不是比较它。你真的想要@array == undef
- 但这也不对。
您需要摆脱检查数组是否“已定义”的想法。您真正感兴趣的是数组是否为空。Perl 有一个聪明的技巧可以帮助你解决这个问题。
如果您在 Perl 期望看到单个(标量)值的地方使用 Perl 数组,它会为您提供数组中元素的数量。所以你可以编写如下代码:
my $number_of_elements = @an_array;
if
or条件中的布尔逻辑检查while
是单个标量值。因此,如果要检查数组是否包含任何元素,可以使用如下代码:
if (@array) {
# @array contains data
} else {
# @array is empty
}
要在数组包含元素时循环,您可以简单地编写:
while (@array) {
# do something
}
但是在这里,您想在数组为空时做一些事情。为此,您可以反转while
条件逻辑(使用!
“not”):
while (!@array) {
# do something
}
或者您可以切换到使用until
测试(与 相反while
):
until (@array) {
# do something
}
我将不得不停在那里。我希望这能让您深入了解您的代码有什么问题。恐怕这种程度的错误也会渗透到您的其余代码中。
如上所述,限制STDIN
为五行
use warnings;
use strict;
use feature 'say';
my @input;
while (<STDIN>) {
chomp;
push @input, $_;
last if @input == 5;
}
say for @input;
在发布的代码中还有其他内容需要评论。虽然在Dave Cross answer中详细阐述了其中的大部分内容,但我想在从文件句柄读取时解决上下文业务。
“钻石”运算符<>
是上下文感知的。来自I/O 操作员 (perlop)
如果
<FILEHANDLE>
在查找列表的上下文中使用 a,则返回包含所有输入行的列表,每个列表元素一行。这种方式很容易增长到相当大的数据空间,因此请谨慎使用。
在通常的while
循环中<>
是在标量上下文中
while (my $line = <$fh>)
并且它是相同的,while (<$fh>)
因为它默认分配给$_
变量,一个标量。
但是如果我们分配给一个数组,比如说从一个文件句柄$fh
中打开一个文件
my @lines = <$fh>;
然后<>
运算符在列表上下文中工作。它读取所有行,直到看到 EOF(文件结尾),此时它返回所有行,这些行分配给@lines
. 请记住,每一行都有其换行符。您可以通过以下方式将它们全部删除
chomp @lines;
因为chomp也适用于列表。
当STDIN
输入来自键盘时,这会引发一个问题,<>
因为 EOF 不是自己出现的,因此会等待更多输入。它通常在 Unixy 系统上以Ctrl+D
†给出(在 Windows 上为 Ctrl+Z)。
因此,原则上,您可以使用@array = <STDIN>
并退出输入,Ctrl+D
但这对于预期从键盘输入的输入可能有点尴尬,因为它主要意味着需要逐行处理。如果STDIN
来自文件,则不那么不寻常,
script.pl < input.txt
或命令行上的管道
some command with output | script.pl
我们确实得到了 EOF(由EOT提供)。
但我还是会坚持while
阅读的习惯STDIN
,逐行处理。
† 这Ctrl+D
就是通常的引用方式,但实际上是d
用Ctrl
. 请注意,Ctrl
and c
(标记为Ctrl+C
)的作用完全不同;它发送SIGINT
信号,如果没有被捕获,则终止整个程序。