2017-02-07 1 views
0

Ich versuche eine Datei zu öffnen, zu scannen und das Programm die Anzahl der positiven, negativen und Nullen auszudrucken. Ich habe das Programm erfolgreich Dateien öffnen, aber das Finden der "Frequenz" ist, was mir Probleme bereitet. Ich war am Tag des Unterrichts krank und konnte anscheinend keine Hilfe zu meiner speziellen Aufforderung finden. Hier ist, was ich bisher habe:Wie finde ich die spezifische Menge/Häufigkeit von positiven, negativen und ganzen Zahlen in einer Datei? (Perl)

#!/usr/bin/perl 
use strict; 
use warnings; 
my ($ctrZ) = (0); 
while(my $num = <DATA>) { 
     chomp($num); 
     ## print "num=[$num]\n"; 
     if ($num =~ /^-\d+$/) { 
       $ctrZ++; 
     } 

printf("freq(0):%9s\n", $ctrZ); 

exit; 
__DATA__ 
19 
-22 
498 
512 
15 
-932 
0 
22 
808 
17 
-32 

Hinweis: Unser Professor gab uns eine Datei zu verwenden. Es ist eine TXT-Datei mit einer einzelnen Nummer in jeder Zeile.

+1

http: //perldoc.perl. org/perlop.html # Relationale Operatoren – toolic

+0

Brauchen Sie wirklich Kommentare wie 'chomp ($ infile); #Chomps die Variable $ infile.' – Borodin

+0

Ja, unser Professor bevorzugt uns, solche zu haben. Außerdem habe ich den falschen Code hinzugefügt, um damit zu beginnen. Das habe ich. Ich muss nur herausfinden, wie viele 0 ganze Zahlen in der Datei sind. –

Antwort

1

Es gibt einige Probleme mit Ihrem Code, aber die große Gefahr, ist dies:

if ($infile) { 
     $Pos_Int++; 
     $Neg_Int++; 
     $Zer_Int++; 
} 

, die nur ist, den Inhalt $infile Auswertung, die der Dateiname ist. Es wird immer wahr sein, und deshalb werden Sie immer alle Ihre Zähler um eins erhöhen.

Also alles, was Sie hier tun, ist im Grunde Linien zählen.

würde vorschlagen, ich aber auch, dass Sie nicht brauchen: eine Datei

open(FHIN, '<', $infile); #Opens the file prompted by user. 
my @lines = <FHIN>; #Variable storing the number of lines in the file. 
chomp(@lines); 
close(FHIN); 

Open, es in ein Array lesen, dann das Array iterieren?

Warum nicht stattdessen Zeile für Zeile mit einer while-Schleife (es verwendet auch weniger Speicher).

Auch - guter Stil ist die Verwendung von lexikalischen Dateihandles anstelle eines Großbuchstabennamens, der ein globaler Geltungsbereich ist.

So:

open (my $input, '<', $infile) or die $!; #check return code for errors. 
while (my $line = <$input>) { #iterate the input line by line, setting $_ for each. 
    $Pos_Int++ if $line > 0; 
    $Neg_Int++ if $line < 0; 
    $Zer_Int++ if $line == 0; 
} 

den Trick tun sollten - aber bedenken, spielt es keine Eingabeüberprüfung tun. Reguläre Ausdrücke könnten dort helfen, wenn es nötig ist.

auch:

if (-e $infile) { #If the file can't be found, it will exit. 

    } else { 
     print ("No such file exists. Program closing.\n"); 
      exit; 
} 

Dies ist überflüssig, denn man kann - und sollte - Falle der Return-Code von open. Wenn Sie das tun, fangen Sie andere Bedingungen wie die Datei, die nicht lesbar ist, oder eine unterbrochene symbolische Verknüpfung oder eine Reihe anderer Probleme.

z.

open (my $input, '<', $infile) or die "Problem opening file: $!"; 

$! geben Ihnen einen Fehlercode, der auch ein bisschen mehr sinnvoll ist - es wird Ihnen sagen, den Unterschied zwischen ‚keine solche Datei oder das Verzeichnis‘ und ‚Zugriff verweigert‘ zum Beispiel.

+1

Es lohnt sich auch darauf hinzuweisen, dass der Existenztest überflüssig ist, da der Status von "offen" ohnehin überprüft werden muss. – Borodin

+0

Guter Punkt. Ich werde ändern. – Sobrique

+1

Nur eine Anmerkung: * redundant * in amerikanischem Englisch kann etwas mehr wie * exzessiv *, * verschwenderisch * oder * über normal * bedeuten. Zum Beispiel ist Zwei-Faktor-Authentifizierung "redundante" Sicherheit. Deshalb bleibe ich auf diesen Seiten bei * überflüssig *. – Borodin

-1

Sie können den Operator <=> verwenden, um genau das zu erhalten, was Sie möchten. Nach perldoc perlop:

Binary "<=>" gibt -1, 0 oder 1, je nachdem, ob die linke Argument numerisch kleiner, gleich oder größer als der rechte Argument.

So:

$ perl -MData::Dumper -wne '$count{$_ <=> 0}++; END { print Dumper(\%count); }' numbers.txt 

Unter der Annahme, numbers.txt enthält folgende Komponenten:

111 
0 
-892 
-664 
21 
0 
63 
868 
-351 
-263 
467 
-58 
625 
724 
0 
0 
990 
107 
-739 
-501 
-386 
909 
-96 
0 
-735 

ausgegeben:

$VAR1 = { 
      '0' => 5, 
      '1' => 10, 
      '-1' => 10 
     }; 
Verwandte Themen