【问题标题】:Perl while loop using read()Perl while 循环使用 read()
【发布时间】:2019-02-07 07:29:32
【问题描述】:

我想使用read 读取文本文件data.txt。 我想一次读取每行的前四个整数。

data.txt

line1 0101020102
line2 2010201001
line3 0201010201

line1 等是文件的一部分。

这就是我现在能做的事情

Perl

my $data;
my $IN;
my $n = 0;

$line = 1;

open($IN, '<', "data.txt") or die " Error";

while ( $line != 0 ) {
    seek($IN, 6, SEEK_SET);
    $line = read($IN, $data, 4);
    seek($IN, 0, SEEK_SET);
}

问题在于,使用这个while 循环,Perl 一直在无限循环中读取第一行。

我该如何处理这个问题?

【问题讨论】:

  • 为什么它会在每次读取后seek() 到文件开头?
  • 您认为在这里使用read 是个好主意(不是)还是只是在尝试使用运算符?

标签: perl


【解决方案1】:

我认为你误解了seek() 的作用。使用SEEK_SET 作为第三个参数,第二个参数被解释为从文件开始测量的要移动到的位置。所以每次你运行这条线:

seek($IN, 6, SEEK_SET);

它总是移动到文件中的第七个位置(显然,它总是在同一行)。然后当你运行这一行时:

seek($IN, 0, SEEK_SET);

它总是回到文件的开头。

最初,我认为解决方案是将SEEK_SET 更改为SEEK_CUR(将第二个参数解释为相对于当前位置移动的量),但它比这更复杂一些。这是我如何让它工作的:

seek($IN, 6, SEEK_CUR); # Move forward six spaces
$line = read($IN, $data, 4);
seek($IN, 7, SEEK_CUR); # Move forward seven places

但实际上,正则表达式是这里最好的方法。

while(<$IN>) {
    ($data) = /\s(\d{4})/;
    print "$data\n";
}

【讨论】:

  • 请注意,这在 Windows 上不起作用,因为您假设一个额外的行终止符,而 Windows 使用两个