如何使数组中的 STDIN 停止? (PERL)
How do I make the STDIN in the Array stop? (PERL)
我的@array 不会停止接收 STDIN...
my @array = undef;
while (@array = undef){
@array = <STDIN>;
for (@array[x]=5){
@array = defined;
}
}
如前所述,将 STDIN
限制为五行
use warnings;
use strict;
use feature 'say';
my @input;
while (<STDIN>) {
chomp;
push @input, $_;
last if @input == 5;
}
say for @input;
在发布的代码中还有其他要评论的地方。当从文件句柄读取时,, I'd like to address the business of context 中详细清除了很多内容。
"diamond" 运算符 <>
是上下文感知的。来自 I/O Operators (perlop)
If a <FILEHANDLE>
is used in a context that is looking for a list, a list comprising all input lines is returned, one line per list element. It's easy to grow to a rather large data space this way, so use with care.
在通常的 while
循环中,<>
在标量上下文中
while (my $line = <$fh>)
它与 while (<$fh>)
相同,因为它默认分配给 $_
variable,一个标量。
但是如果我们分配给一个数组,比如从打开文件的文件句柄$fh
my @lines = <$fh>;
then <>
运算符在列表上下文中工作。它读取所有行直到它看到 EOF(文件结尾),此时它 returns 所有行,这些行被分配给 @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 提供)。
但是我在阅读STDIN
的时候还是会坚持一个习惯while
,逐行处理。
† Ctrl+D
通常是这样称呼的,但实际上是用 Ctrl
键入小写的 d
。请注意,Ctrl
和 c
(标记为 Ctrl+C
)做的事情完全不同;它发送 SIGINT
信号,如果没有被捕获则终止整个程序。
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
而不是比较它。你真的想要 @array == undef
- 但那也不对。
您需要摒弃这种检查数组是否为 "defined" 的想法。您真正感兴趣的是数组是否为空。 Perl 有一个聪明的技巧可以帮助您解决这个问题。
如果您在 Perl 希望看到单个(标量)值的地方使用 Perl 数组,它会为您提供数组中元素的数量。所以你可以这样写代码:
my $number_of_elements = @an_array;
if
或 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
}
我要到此为止了。我希望这能让您深入了解您的代码有什么问题。恐怕这种程度的错误也会渗透到您的其余代码中。
我的@array 不会停止接收 STDIN...
my @array = undef;
while (@array = undef){
@array = <STDIN>;
for (@array[x]=5){
@array = defined;
}
}
如前所述,将 STDIN
限制为五行
use warnings;
use strict;
use feature 'say';
my @input;
while (<STDIN>) {
chomp;
push @input, $_;
last if @input == 5;
}
say for @input;
在发布的代码中还有其他要评论的地方。当从文件句柄读取时,
"diamond" 运算符 <>
是上下文感知的。来自 I/O Operators (perlop)
If a
<FILEHANDLE>
is used in a context that is looking for a list, a list comprising all input lines is returned, one line per list element. It's easy to grow to a rather large data space this way, so use with care.
在通常的 while
循环中,<>
在标量上下文中
while (my $line = <$fh>)
它与 while (<$fh>)
相同,因为它默认分配给 $_
variable,一个标量。
但是如果我们分配给一个数组,比如从打开文件的文件句柄$fh
my @lines = <$fh>;
then <>
运算符在列表上下文中工作。它读取所有行直到它看到 EOF(文件结尾),此时它 returns 所有行,这些行被分配给 @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 提供)。
但是我在阅读STDIN
的时候还是会坚持一个习惯while
,逐行处理。
† Ctrl+D
通常是这样称呼的,但实际上是用 Ctrl
键入小写的 d
。请注意,Ctrl
和 c
(标记为 Ctrl+C
)做的事情完全不同;它发送 SIGINT
信号,如果没有被捕获则终止整个程序。
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
而不是比较它。你真的想要 @array == undef
- 但那也不对。
您需要摒弃这种检查数组是否为 "defined" 的想法。您真正感兴趣的是数组是否为空。 Perl 有一个聪明的技巧可以帮助您解决这个问题。
如果您在 Perl 希望看到单个(标量)值的地方使用 Perl 数组,它会为您提供数组中元素的数量。所以你可以这样写代码:
my $number_of_elements = @an_array;
if
或 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
}
我要到此为止了。我希望这能让您深入了解您的代码有什么问题。恐怕这种程度的错误也会渗透到您的其余代码中。