[求助]while读入数据,操作取舍问题!Thank you advance!



QUOTE:
原帖由 hitsubunnu 于 2008-12-15 09:51 发表


MMMIX 你说的是注意这个吗?

你提的这句话本身就有问题。使用 $. 的问题一言以蔽之就是,$. 只有在 filehandle close 的时候才会 reset,这样若你通过 <> 处理命令行上的多个文件,或者是前面的 filehandle 用完了忘了 close,那么 $. 的值都会出问题。

详见 perlvar 对 $. 的描述。



QUOTE:
原帖由 longbow0 于 2008-12-15 09:43 发表
既然所有数据的格式相同,直接提取就可以了。

37898..39115        -        405        16128032         


while () {
    if (/^(\d+)\.{2}(\d+)\s+([-|+])\s+(\d+)\s+(\d+)/) {
        $A1 = $1; ...

sweet


QUOTE:
原帖由 longbow0 于 2008-12-15 09:43 发表
既然所有数据的格式相同,直接提取就可以了。

37898..39115        -        405        16128032         


while () {
    if (/^(\d+)\.{2}(\d+)\s+([-|+])\s+(\d+)\s+(\d+)/) {
        $A1 = $1; ...

谢谢!这样也可以,其实实际情况比我列出的还要复杂,每一行还有文字描述,里面还有“-”等符号,还要提取文字包含这些,像我perl学得不深,用起来一连串的正则表达式很容易出错,觉得还是前面的方法好用些。


QUOTE:
原帖由 MMMIX 于 2008-12-15 10:04 发表

你提的这句话本身就有问题。

这句话跟你讲的是一个意思。可能是我没贴全 让你产生歧义了 下面是翻译的全文

QUOTE:
译者注:通俗的说,这个内置变量就跟数据库中的记录指针非常相似,它的值就是你当前所读文件中的当前行号。
关于“$.”最后要说明的一点是,一个程序中只有一个“$.”变量。如果你在从多个文件句柄中读数据,那么“$.”变量保存了最近读过的文件句柄中的当前记录号。如果你想要更复杂的解决此问题的方法那么你可以使用类似IO::FILE对象。这些对象都有一个input_line_number方法。

关于你提到的    前面的 filehandle 用完了忘了 close
这是写程序的人的问题

为便于他人参考 特意标注

如果你在从多个文件句柄中读数据,那么“$.”变量保存了最近读过的文件句柄中的当前记录号。



QUOTE:
原帖由 hitsubunnu 于 2008-12-15 10:40 发表


这句话跟你讲的是一个意思。

不是。我要说的是 $. 可能跨文件累加。

QUOTE:
关于你提到的    前面的 filehandle 用完了忘了 close
这是写程序的人的问题

话虽如此,但这也是使用 $. 要注意的地方。

另外,对于通过 <> 访问命令行上的文件时,使用 $. 也是成问题的。
测试了一下 并不会产生累加   只要严格控制文件句柄 就没问题

[Copy to clipboard] [ - ]
CODE:
use strict;
use warnings;

my $file1 = 'C:\\perlfile\\relutes\\tmp2.txt';
my $file2 = 'C:\\perlfile\\relutes\\tmp.txt';

open(FF,$file1);
open(GG,$file2);

while(<FF>){
        print $.,"\n";
        while(<GG>){
                print "-$.\n";
        }
}

close(GG);
close(FF);



[Copy to clipboard] [ - ]
CODE:
1
-1
-2
-3
-4
2
3
4

不错,问题总是越辩越明朗!谢谢二位,论坛上有了像二位这样的perl爱好者与热心者,真是大好事!


QUOTE:
原帖由 hitsubunnu 于 2008-12-15 10:59 发表
测试了一下 并不会产生累加   

那你再试下这个

[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/perl

use strict;
use warnings;

my @argv = @ARGV;

while (<>) {
    print "\$. = $.\n";
}

for my $f (@argv) {
    open my $fh, $f or die "Can't open $f: $!";
    while (<$fh>) {
        print "\$. = $.\n";
    }
}



QUOTE:
$ ./t.pl t.pl t.pl

或者把后面的 for 循环换为

[Copy to clipboard] [ - ]
CODE:
my $fh;
for my $f (@argv) {
    open $fh, $f or die "Can't open $f: $!";
    while (<$fh>) {
        print "\$. = $.\n";
    }
}



[Copy to clipboard] [ - ]
CODE:
my $fh;
for my $f (@argv) {
    open $fh, $f or die "Can't open $f: $!";
    while (<$fh>) {
        print "\$. = $.\n";
    }
}

你把程序改一下就清楚了

[Copy to clipboard] [ - ]
CODE:
for my $f (@argv) {
    open FF, $f or die "Can't open $f: $!";
    while (<FF>) {
        print "\$. = $.\n";
    }
}

这里$. 一直对应都是FF这个文件句柄  

是你将两个文件句柄变成了一个文件句柄  $. 对应的还是当前文件句柄
拆分的更彻底一些就是

[Copy to clipboard] [ - ]
CODE:
open FF, $argv[0] or die "Can't open  $!";
    while (<FF>) {
        print "$_   :   \$. = $.\n";
    }

    open FF, $argv[1] or die "Can't open  $!";
    while (<FF>) {
        print "$_   :   \$. = $.\n";
    }

其实还是归结为   文件句柄用完必须关闭 !