возьмите массив ввода от пользователя в Perl

когда я использую этот код

print "nEnter !0 numbers nn";
@arr=<STDIN>;
chomp @arr;

Она продолжает забирать согласно пользователю, пока я использую ctrl+z и нажмите клавишу Ввод. Я хочу ограничить количество вводимых пользователем данных списком. Для этого я старался

print "nEnter !0 numbers nn";
for($i=0;$i<10;$i++)
{
@arr[$i]=<STDIN>;
chomp @arr;
} 

но это старение падать в бесконечный цикл, и я должен использовать ctrl+c

как я могу ограничить свой цикл, чтобы ввести только 10 пользователей ввода

1 ответов


основная проблема здесь заключается в том, что вы используете @arr[$i] когда вы должны использовать $arr[$i]. Использование массива sigil @, вы применяете контекст списка к дескриптору файла, что заставляет его читать как можно больше значений. Когда в скалярном контексте он просто прочитает одно значение, а затем перейдет к следующей итерации. Другими словами, это должно быть так:

$arr[$i] = <STDIN>;

однако о вашем коде можно сказать гораздо больше. Например, совершенно необязательно использовать определенный индекс, когда присваивая номера, вы можете просто использовать push

for (1 .. 10) {
    my $num = <STDIN>;
    chomp $num;
    push @arr, $num;
}

будьте осторожны, чтобы сохранить скалярный контекст. Технически, вы можете сделать push @arr, <STDIN>, но это снова поместит дескриптор файла в контекст списка. Этот путь приятен и удобочитаем.

другой способ сделать то же самое, не используя "внешний" счетчик, использует сам массив в качестве условия цикла. Когда в скалярном контексте массив возвращает свой размер. Мы можем использовать это с while как это:

while (@arr < 10) {
    my $num = <STDIN>;
    chomp $num;
    push @arr, $num;
}

теперь, если вы установите переменную для подсчета...

my @arr;
my $count = 10;
print "Enter $count numbers: ";
while (@arr < $count) {

...ваша программа теперь масштабируема.

большую часть времени использование STDIN специально не требуется или не требуется. Например, вы можете захотеть, чтобы ваша программа работала также с именем файла в качестве входных данных. Использование "алмазного оператора"<> позволяет Perl самостоятельно решить, следует ли читать из <ARGV> или <STDIN>. Таким образом, вы можете вместо этого использовать:

my $num = <>;

вы должны всегда используйте

use strict;
use warnings;

эти две прагмы имеют короткую кривую обучения, но кодирование без них трудно и опасно.