<数据>防止foreach循环被执行,为什么? :) [英] <DATA> prevents foreach loop from being executed, why? :)

查看:108
本文介绍了<数据>防止foreach循环被执行,为什么? :)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个嵌套的foreach循环。如果我使用下面的代码:

$ $ $ $ $ $ $ $ $ $ $ $ foreach(@directories){
my $ actual_directory = $ _;
打印\实际目录:。$ actual_directory。\\\
;

foreach(@files){
my $ file_name = $ _;
my $ actual_file = $ actual_directory。$ file_name;
打印$ actual_file。\\\
;

打开(DATA,$ actual_file)或死Nelzeotevřítzdrojovýsoubor:$!\\\
;
my $ line_number = 0; (< DATA>){
#my @znaky = split('',$ _);


#my $ poradi = $ znaky [0]; #poradi nukleotidu
#my $ hodnota = $ znaky [1]; #hodnota

#my @temp = $ files_to_sum_of_lines {$ actual_file};
#$ temp [$ line_number] + = $ hodnota;
#$ files_to_sum_of_lines {$ actual_file} = @temp;

#$ line_number + = 1;
#}
#close(DATA);




$ b $我有这个输出:

 实际目录:/ home / n / Plocha / counting_files / 1 / 

/ home / n / Plocha / counting_files / 1 /a.txt
/home/n/Plocha/counting_files/1/b.txt

实际目录:/ home / n / Plocha / counting_files / 2 /

/home/n/Plocha/counting_files/2/a.txt
/home/n/Plocha/counting_files/2/b.txt
>时取消注释,那么我就放弃了a.txt和b .txt,所以输出如下所示:

 实际目录:/ home / n / Plocha / counting_files / 1 / 

/home/n/Plocha/counting_files/1/a.txt
/home/n/Plocha/counting_files/1/b.txt

实际目录:/ home / n / Plocha / counting_files / 2 /

/ home / n / Plocha / counting_files / 2 /
/ home / n / Plocha / counting_files / 2 /

这个 while(< DATA>)如何防止我的foreach正在执行?
任何帮助将不胜感激。非常感谢。

解决方案

除了不使用 DATA 使用词法循环变量和词法文件句柄。此外,Perl内置的 $。会记录您的行号。

 为我的$ actual_directory(@directories){
打印\实际目录:。$ actual_directory。\\\
;

foreach my $ file_name(@files){
my $ actual_file = $ actual_directory。$ file_name;
打印$ actual_file。\\\
;

打开我的$ INPUT,'<',$ actual_file
或者Nelzeotevřítzdrojovýsoubor:$!\\\
;

while(my $ line =< $ INPUT>){
my @znaky = split('',$ line);
my $ poradi = $ znaky [0]; #poradi nukleotidu
my $ hodnota = $ znaky [1]; #hodnota
@temp = $ files_to_sum_of_lines {$ actual_file};
$ temp [$。 ] + = $ hodnota;
$ files_to_sum_of_lines {$ actual_file} = @temp;
}
close $ INPUT;




$ b $ p
$ b $ p另一方面,如果在那里有逻辑错误。

$ p $ #!/ usr / bin / perl

使用警告;严格使用

使用鲤鱼;
使用File :: Find;
使用File :: Spec :: Functions qw(catfile canonpath);

my%counts;
find(\& count_lines_in_files,@ARGV);

for my $ dir(sort keys%counts){
print$ dir\\\
;
my $ dircounts = $ counts {$ dir};
for $ file(sort keys%{$ dircounts}){
printf\t%s:%d \\\
,$ file,$ dircounts-> {$ file};
}
}

sub count_lines_in_files {
my $ file = canonpath $ _;
my $ dir = canonpath $ File :: Find :: dir;
my $ path = canonpath $ File :: Find :: name;

返回除非-f $路径;

$ counts {$ dir} {$ file} = count_lines_in_file($ path);
}

sub count_lines_in_file {
my($ path)= @_;

my $ ret =打开我的$ fh,'<',$ path;

除非($ ret){
carp无法打开'$ path':$!;
return;
}
1,而< $ fh>;

my $ n_lines = $ .;

close $ fh
or croak无法关闭'$ path':$!;

返回$ n_lines;
}


I have two nested foreach loops. If I use this code:

foreach (@directories) {
    my $actual_directory = $_;
    print "\nactual directory: ".$actual_directory."\n";

    foreach (@files) {
        my $file_name = $_; 
        my $actual_file = $actual_directory.$file_name;
        print $actual_file."\n";

        open(DATA, $actual_file) or die "Nelze otevřít zdrojový soubor: $!\n";
        my $line_number = 0;

        #   while (<DATA>){
        #       my @znaky = split(' ',$_);
        #       my $poradi = $znaky[0]; #poradi nukleotidu
        #       my $hodnota = $znaky[1]; #hodnota

        #       my @temp = $files_to_sum_of_lines{$actual_file};
        #       $temp[$line_number] += $hodnota;    
        #       $files_to_sum_of_lines{$actual_file} = @temp;

        #       $line_number+=1;
        #   }
        #   close(DATA); 
    }
} 

I got this output:

actual directory: /home/n/Plocha/counting_files/1/

/home/n/Plocha/counting_files/1/a.txt
/home/n/Plocha/counting_files/1/b.txt

actual directory: /home/n/Plocha/counting_files/2/

/home/n/Plocha/counting_files/2/a.txt
/home/n/Plocha/counting_files/2/b.txt

However, if I uncomment "while (<DATA>){ }", I loose a.txt and b.txt, so the output looks like this:

actual directory: /home/n/Plocha/counting_files/1/

/home/n/Plocha/counting_files/1/a.txt
/home/n/Plocha/counting_files/1/b.txt

actual directory: /home/n/Plocha/counting_files/2/

/home/n/Plocha/counting_files/2/
/home/n/Plocha/counting_files/2/

How can this while (<DATA>) prevent my foreach from being executed? Any help will be appreciated. Thanks a lot.

解决方案

In addition to not using DATA, try using lexical loop variables, and lexical filehandles. Also, Perl's built-in $. keeps track of line numbers for you.

for my $actual_directory (@directories) {
    print "\nactual directory: ".$actual_directory."\n";

    foreach my $file_name (@files) {
        my $actual_file = $actual_directory.$file_name;
        print $actual_file."\n";

        open my $INPUT, '<', $actual_file
            or die "Nelze otevřít zdrojový soubor: $!\n";

        while (my $line = <$INPUT>) {
               my @znaky = split(' ', $line);
               my $poradi = $znaky[0]; #poradi nukleotidu
               my $hodnota = $znaky[1]; #hodnota
               @temp = $files_to_sum_of_lines{$actual_file};
               $temp[ $. ] += $hodnota;
               $files_to_sum_of_lines{$actual_file} = @temp;
        }
        close $INPUT; 
    }
}

On the other hand, I can't quite tell if there is a logic error in there. Something like the following might be useful:

#!/usr/bin/perl

use warnings; use strict;

use Carp;
use File::Find;
use File::Spec::Functions qw( catfile canonpath );

my %counts;
find(\&count_lines_in_files, @ARGV);

for my $dir (sort keys %counts) {
    print "$dir\n";
    my $dircounts = $counts{ $dir };
    for my $file (sort keys %{ $dircounts }) {
        printf "\t%s: %d\n", $file, $dircounts->{ $file };
    }
}

sub count_lines_in_files {
    my $file = canonpath $_;
    my $dir  = canonpath $File::Find::dir;
    my $path = canonpath $File::Find::name;

    return unless -f $path;

    $counts{ $dir }{ $file } = count_lines_in_file($path);
}

sub count_lines_in_file {
    my ($path) = @_;

    my $ret = open my $fh, '<', $path;

    unless ($ret) {
        carp "Cannot open '$path': $!";
        return;
    }
    1 while <$fh>;

    my $n_lines = $.;

    close $fh
        or croak "Cannot close '$path': $!";

    return $n_lines;
}

这篇关于&lt;数据&GT;防止foreach循环被执行,为什么? :)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆