2011-12-10 43 views
2

为什么我的Perl代码没有打印出任何东西?我一直在研究这个问题,现在我正在使用一个文本文件,其中包含大量不同的数据,每个数据都用逗号分隔,表示它是一列。使用文本文件的Perl代码

这是我的代码:

#!/usr/bin/perl 

open (FILE, 'census2008.txt'); 

my @SumLevArray; 
my @StNameArray; 
my @CtyNameArray; 
my @PopEstimateArary; 
my @BirthsArray; 
my @DeathsArray; 

$i = 0; 
$temp = 0; 
$lowestBirthRates = 100000000; 
$highestBirthRates = 0; 
$size = 0; 


while (<FILE>) 
{ 
chomp; 
($sumlev, $stname,$ctyname,$popestimate2008,$births2008,$deaths2008) = split(","); 
push (@SumLevArray, $sumlev); 
push (@StNameArray, $stname); 
push (@CtyNameArray, $ctyname); 
push (@PopEstimateArary, $popestimate2008); 
push (@BirthsArray, $births2008); 
push (@DeathsArray, $deaths2008); 
} 
$size = @BirthsArray; 

while ($i < $size) 
{ 
if($SumLevArray[$i] == " 040"){ 
$temp = $BirthsArray[$i]/$PopEstimateArary[$i]/541; 
if(($lowestBirthRates > $temp) &&($temp > 0)){ 
$lowestBirthRates = $temp; 
} 
if($highestBirthRates < $temp){ 
$highestBirthRates = $temp; 
} 

} 
$i = $i + 1; 
} 

print "\n"; 

print "Lowest birth rate in LOW-STATE: "; 
print $lowestBirthRates; 
print " per 541\n"; 

print "Highest birth rate in HIGH-STATE: "; 
print $highestBirthRates; 
print " per 541\n"; 

print "In Washington:\n"; 

print " Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541\n"; 

print " Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541\n"; 


close (FILE); 
exit 
+4

**总是**用'use strict;启动一个Perl程序;使用警告;'当你打开一个文件时,测试一下你是否成功了perl [perldoc中的示例](http://perldoc.perl.org/functions/open.html)。 – Quentin

+0

并且不要推出自己的CSV解析器,使用[Text :: CSV](https://metacpan.org/module/Text::CSV),它更快,并且处理大量的边缘情况。 – Quentin

+0

@Quentin:原则上我同意'Text :: CSV'的建议,但看起来OP在使用模块之前还有很长的路要走。这是学习曲线的一部分 – Zaid

回答

1

除了像其他人所建议的那样使用Text :: CSV,为了好玩,我已经重写了代码,因为我可能已经写了它。它包含了很多这里提出的建议以及我的一些个人风格选择。如果您有任何疑问,请询问。此外,如果您可以发布一些示例数据,我可以检查它是否有效。

#!/usr/bin/env perl 

use strict; 
use warnings; 

my $lowestBirthRates = 100000000; 
my $highestBirthRates = 0; 

my $filename = 'census2008.txt'; 
open (my $fh, '<', $filename) or die "Cannot open $filename: $!"; 

my %data; 

while (<$fh>) { 
    chomp; 
    my ($sumlev, $stname,$ctyname,$popestimate2008,$births2008,$deaths2008) = split(","); 

    push (@{$data{SumLev}}, $sumlev); 
    push (@{$data{StName}}, $stname); 
    push (@{$data{CtyName}}, $ctyname); 
    push (@{$data{PopEstimate}}, $popestimate2008); 
    push (@{$data{Births}}, $births2008); 
    push (@{$data{Deaths}}, $deaths2008); 
} 

my $i = 0; 
my $size = @{$data{Births}}; 

while ($i < $size) { 

    if ($data{SumLev}[$i] eq " 040"){ 
    #if ($data{SumLev}[$i] == 40){ 

    my $temp = $data{Births}[$i]/$data{PopEstimate}[$i]/541; 

    if($lowestBirthRates > $temp && $temp > 0){ 
     $lowestBirthRates = $temp; 
    } 

    if ($highestBirthRates < $temp){ 
     $highestBirthRates = $temp; 
    } 

    } 

    $i++; 
} 

print <<REPORT; 
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541 
Highest birth rate in HIGH-STATE: $highestBirthRates per 541 
In Washington: 
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541 
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541 
REPORT 

,如果您有有Perl版本5.14或更高版本安装的奢侈,你可以使用一个更清晰的语法,其中push可直接乘坐引用,并在each可以给所关注的索引以及价值。

#!/usr/bin/env perl 

use strict; 
use warnings; 

use 5.14.0; 

my $lowestBirthRates = 100000000; 
my $highestBirthRates = 0; 

my $filename = 'census2008.txt'; 
open (my $fh, '<', $filename) or die "Cannot open $filename: $!"; 

my %data = (
    SumLev => [], 
    StName => [], 
    CtyName => [], 
    PopEstimate => [], 
    Births => [], 
    Deaths => [], 
); 

while (<$fh>) { 
    chomp; 
    my ($sumlev, $stname,$ctyname,$popestimate2008,$births2008,$deaths2008) = split(","); 

    push ($data{SumLev}, $sumlev); 
    push ($data{StName}, $stname); 
    push ($data{CtyName}, $ctyname); 
    push ($data{PopEstimate}, $popestimate2008); 
    push ($data{Births}, $births2008); 
    push ($data{Deaths}, $deaths2008); 
} 

while (my ($i, $births) = each $data{Births}) { 

    if ($data{SumLev}[$i] eq " 040"){ 
    #if ($data{SumLev}[$i] == 40){ 

    my $temp = $births/$data{PopEstimate}[$i]/541; 

    if($lowestBirthRates > $temp && $temp > 0){ 
     $lowestBirthRates = $temp; 
    } 

    if ($highestBirthRates < $temp){ 
     $highestBirthRates = $temp; 
    } 

    } 
} 

print <<REPORT; 
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541 
Highest birth rate in HIGH-STATE: $highestBirthRates per 541 
In Washington: 
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541 
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541 
REPORT 

最后这里是使用Tie::Array::CSV一个实现我写信给能够使用CSV文件,就像在Perl的2D阵列(即ArrayRefs的阵列)。它使用Text::CSV进行分析,并使用Tie::File进行线路访问。这意味着您不需要像前面的例子那样将所有数据存储在内存中。

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Tie::Array::CSV; 

my $lowestBirthRates = 100000000; 
my $highestBirthRates = 0; 

my $filename = 'census2008.txt'; 
tie my @data, 'Tie::Array::CSV', $filename 
    or die "Cannot tie $filename: $!"; 


foreach my $row (@data) { 
    my ($sumlev, $stname, $ctyname, $popest, $births, $deaths) = @$row; 

    if ($sumlev eq " 040"){ 
    #if ($sumlev == 40){ 

    my $temp = $births/$popest/541; 

    if($lowestBirthRates > $temp && $temp > 0){ 
     $lowestBirthRates = $temp; 
    } 

    if ($highestBirthRates < $temp){ 
     $highestBirthRates = $temp; 
    } 

    } 
} 

print <<REPORT; 
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541 
Highest birth rate in HIGH-STATE: $highestBirthRates per 541 
In Washington: 
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541 
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541 
REPORT 
1

尝试:

open (FILE, 'census2008.txt') or die $!; 

开放可能没有你知道它要失败的。

+0

你没有工作,我主要在出生率最低的问题。 – user977154

+0

那么我认为@丹有你的答案:) –

1

当您打印某些内容时,以换行符结尾将导致它立即被打印,否则文本将进入打印缓冲区但缓冲区不会被刷新。

+0

它现在打印出零,你知道它为什么会这样做吗? – user977154

+0

因为值为零 – Dan

+0

即使我拿出最低生产率= 0它仍然等于零:( – user977154

4

这里最好的帮助工具是use strict; use warnings;。把它放在你编写的每个脚本的顶部,这样可以为你节省大量的时间来调试微不足道的问题。

在这里,有几个i是错过了他们$印。

另外,请考虑学习Perl数据结构食谱:perldoc perldsc。一组散列(技术上的hashrefs)将是一个更可扩展的数据结构选择来存储数据。

1

您应该取消缓冲标准输出。

添加以下后#!/usr/bin/perl

$| = 1; 

话虽如此,这里有一些其他的事情,我建议:

1)在最小use strict;(也劝use warnings

严格意志会迫使你使用“我的”在你尚未这样做的地方声明你的变量。我无法告诉您我看过程序员搜索的次数,并在开启严格检查时搜索容易检测到的错误。 (基于VAR的名字拼写错误是常见的一种)

2)使用开放

open($FILE, "<", 'census2008.txt') || die("Cannot open file!"); 

以下这不仅会通知你,如果一个文件不能打开写(由于使用的die), ,但使用$FILE而不是原始文件句柄会导致该文件在 超出范围时自动关闭。

+0

这应该是'打开$ FILE','<',...'(注意小于,不大于符号 – AFresh1

+0

由于某种原因,当我打字时,我忘记了文件是他正在处理的数据,而不是他正在编写结果的文件。 –

+0

由于perl使用stdio.h是不可能的,所以“unbuffer stdout”是不可能的。是一个缓冲库。设置$ | = 1启用自动刷新,它不会取消缓冲标准输出。 – tadmc

0

尝试修改您的代码第一行:

#!/usr/bin/perl 

use strict; 
use warnings; 

$| = 1; # 

open (FILE, 'census2008.txt'); 

解决所出现的错误/警告后,都应该没问题。

0

要访问数组,您使用i而不是$ i作为索引。
除此之外,我不明白你想在while循环中做什么。

0

有该行的一个问题:

if($SumLevArray[$i] == " 040"){ 

这条线被评估为true的$SumLevArray[$i]"40", "040", " 00040 "

如果$SumLevArray[$i]是一个整数很多值,此行应该是:

if($SumLevArray[$i] == 40){ 

if $SumLevArray[$i]是一个字符串,这行应该是:

if($SumLevArray[$i] eq " 040"){