2011-12-10 65 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"){