我与foreach
循环以及我不太了解的while
进行了不受欢迎的互动。我有一个正常的for
循环,然后是一个foreach
循环通过一个数组。我用两者创建一个字符串(表示文件名),然后打开文件并阅读它。
我使用的代码在这里:
@array=(1,2);
for($y=0;$y<2;$y++)
{
foreach(@array)
{
print "@array\n";
$name="/Users/jorge/$_\_vs_$y\.txt";
print "$name\n";
open(INFILE,"$name") or die "Can't open files!\n";
while(<INFILE>)
{
$line=$_;
}
}
}
,输出为:
array: 1 2
/Users/jorge/1_vs_0.txt
array: 2
/Users/jorge/2_vs_0.txt
array:
/Users/jorge/_vs_1.txt
如果我删除了:
,似乎某种方式while循环缩短了我的数组while(<INFILE>)
如果我改变了foreach,它的工作也是有意的:
foreach $tmp (@array)
并使用$ tmp而不是$ _,它也按预期工作,输出如下:
array: 1 2
/Users/jorge/1_vs_0.txt
array: 1 2
/Users/jorge/2_vs_0.txt
array: 1 2
/Users/jorge/1_vs_1.txt
array: 1 2
/Users/jorge/2_vs_1.txt
array: 1 2
/Users/jorge/1_vs_2.txt
答案 0 :(得分:3)
您在两个嵌套循环上使用$_
作为循环控制变量。相反,你应该为每个循环赋予自己的变量。
内循环不仅改变了外循环的控制变量的值,而且还改变了循环的实际数组。这是因为Perl的for
/ foreach
中的循环控制变量别名数组的元素,所以当<INFILE>
构造时将一行读入$_
,它会用该行覆盖@array
的当前元素。当while
循环完成读取文件后,$_
将从最后<INFILE>
出现为未定义,这意味着@array
中最近处理的元素将始终未定义你回到foreach
循环的顶部。
您还应该使用my
声明变量,使用词法标量而不是裸字作为文件句柄,并使用open
的三参数版本,所以我&#39;我们也在下面做了这些改变。但是,缩小数组问题的解决方案只是对两个循环中的至少一个使用显式变量而不是默认$_
。
my @array = (1, 2);
for (my $y = 0; $y < 2; $y++)
{
foreach my $x (@array) # using $x instead of $_
{
print "@array\n";
my $name = "/Users/jorge/${x}_vs_$y.txt";
print "$name\n";
open my $infile, '<', $name or die "$0: can't open file '$name': $!\n";
while (my $line = <$infile>) # using $line instead of $_
{
# do something with $line here
}
}
}
答案 1 :(得分:1)
您的while循环会覆盖数组内容,因为它使用的$_
是@array
元素的别名。
最好在使用while
,
while (my $line = <INFILE>) {
# ..
}