如何使阵列中的STDIN停止? (PERL)

时间:2017-07-27 22:23:04

标签: arrays perl defined undef

我的@array不会停止参加STDIN ...

my @array = undef;
while (@array = undef){
    @array = <STDIN>;
    for (@array[x]=5){
        @array = defined;
    }
}

2 个答案:

答案 0 :(得分:3)

如澄清,将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中详细说明了很多内容,但我想在阅读文件句柄时解决context的业务问题。

“菱形”运算符<>具有上下文感知功能。来自I/O Operators (perlop)

  

如果在查找列表的上下文中使用<FILEHANDLE>,则返回包含所有输入行的列表,每个列表元素一行。通过这种方式很容易扩展到相当大的数据空间,因此请小心使用。

在通常的while循环中,<>位于标量上下文

while (my $line = <$fh>)

while (<$fh>)相同,因为默认情况下它会分配给标$_ variable

但是,如果我们分配给一个数组,比如说从文件句柄$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的{​​{1}}类型Ctrl。请注意,Ctrlc(标记为Ctrl+C)完全不同;它发送SIGINT信号,如果没有被捕获则终止整个程序。

答案 1 :(得分:3)

my @array = undef;
while (@array = undef){

这两行并没有做到(我认为)你认为他们正在做的事情。

my @array = undef;

这定义了一个具有单个元素的数组,该元素是特殊值undef。我怀疑你真正想要的是:

my @array = ();

创建一个空数组。但Perl数组在首次创建时始终为空,因此可以简化为:

my @array;

第二行重复该错误并添加一个新错误。

while (@array = undef) {

我怀疑你想在这里检查一个空数组,而你正在寻找类似“if @array is undefined”之类的东西。但是你错过了Perl中的赋值运算符(如= })与比较运算符(例如==)不同。所以这行 undef分配给@array而不是比较它。你真的想要{{1} } - 但那也不对。

您需要放弃检查数组是否已“定义”的想法。你真正感兴趣的是数组是否为空。 Perl有一个聪明的技巧可以帮助你解决这个问题。

如果在Perl期望看到单个(标量)值的位置使用Perl数组,它会为您提供数组中元素的数量。所以你可以编写如下代码:

@array == undef

my $number_of_elements = @an_array; if条件中的布尔逻辑检查是单个标量值。因此,如果要检查数组是否包含任何元素,可以使用以下代码:

while

要在数组包含元素时循环,您只需编写:

if (@array) {
  # @array contains data
} else {
  # @array is empty
}

但是在这里,你想在你的数组是空的时候做点什么。为此,您可以反转while (@array) { # do something } 条件逻辑(使用while表示“不”):

!

或者您可以切换到使用while (!@array) { # do something } 测试(与until相反):

while

我将不得不停在那里。我希望这能让您深入了解代码的错误。我担心这种错误程度也会渗透到你的其他代码中。