Fehler in meinem Perl-Programm, den ich nicht versteh...

Rahul0891

Grünschnabel
Hallo,

ich habe ein kleines Programm zum Erstellen von verschiedenen Input-Dateien
für ein Quantenchemie-Programm geschrieben, dass einen Fehler aufweist,
den ich überhaupt nicht blicke.
Nun hat mir jemand dieses Forum empfohlen und ich hoffe hier Antwort zu finden,
anbei schicke ich drei Dateien als zip gepackt.

Ein C++-Quelldatei "Kombination.cpp", das kompilierte "Kombination.out" wird in meinem
Perl-Script "CreateStatisticalPositions.pl" mit system aufgerufen, als Argument von
"CreateStatisticalPositions.pl" wird ein Standard-Input-File (hier "Mayenite.d12")übergeben.

Mein Problem ist in der Subroutine "sub PrintNum"

Code:
sub PrintNum{
     80     print $_[0];
     81     $_[0]=~ s/^\s*( \d{1,3}[\s\d]+\d{1,3})\s*$/$1/;
     82     print $_[0];
     83     my @numbers =split /\s+/,$_[0];
     84     my $NumofNum = @numbers;
     85     my $StdNum = $_[1]+2;
     86
     87     for (my $ctr1=1; $ctr1 < $NumofNum; $ctr1++){
     88         my $line=" " if (($ctr1-1)%15==0||$ctr1==1);
     89         print "Restart line\n" if (($ctr1-1)%15==0||$ctr1==1);
     90         print $line;
     91         print "|$ctr1: $numbers[$ctr1]\n";
     92         for (my $ctr2=&TestDigits($numbers[$ctr1]); $ctr2 < 2; $ctr2++){
     93             $line.=" ";
     94         }
     95         $line.="$numbers[$ctr1] ";
     96         if ((($ctr1)%15==0)||($ctr1==$NumofNum)){
     97             $line.="\n";
     98             if($ctr1<=15){
     99                 $_[$StdNum]=$line;
    100                 print "\nIn Overwrite-line\n";
    101                 print $line;
    102             }
    103             else{
    104                 splice(@$_, $StdNum, 0, $line);
    105                 print "\nIn splice-line\n";
    106                 print $line;
    107             }
    108             $StdNum++;
    109         }
    110         print $line;
    111         print "|$ctr1: $numbers[$ctr1]\n";
    112     }
    113 }

Letzendlich soll $line immer in die Kennzeile des Standard-Inputs geschrieben werden,
dabei ist mein Problem besser erkennbar, wenn man sich die Ausgabe von $line immer anschaut, die ich in "PrintNum" zum Debuggen eingebaut habe,...

Code:
  59  60  61  62  63  64  65  66  67  68  69
 59  60  61  62  63  64  65  66  67  68  69Restart line
 |1: 59
  59 |1: 59
Use of uninitialized value in print at ./Create_Statistical_Positions.pl line 90, <COMBINATION> line 12.
|2: 60
 60 |2: 60
 60 |3: 61
 60  61 |3: 61
 60  61 |4: 62
 60  61  62 |4: 62
 60  61  62 |5: 63
 60  61  62  63 |5: 63
 60  61  62  63 |6: 64
 60  61  62  63  64 |6: 64
 60  61  62  63  64 |7: 65
 60  61  62  63  64  65 |7: 65
 60  61  62  63  64  65 |8: 66
 60  61  62  63  64  65  66 |8: 66
 60  61  62  63  64  65  66 |9: 67
 60  61  62  63  64  65  66  67 |9: 67
 60  61  62  63  64  65  66  67 |10: 68
 60  61  62  63  64  65  66  67  68 |10: 68
 60  61  62  63  64  65  66  67  68 |11: 69
 60  61  62  63  64  65  66  67  68  69 |11: 69

Das ist eine Beispielausgabe des 12. Zyklus, wenn ich die Zahlen 59 70 1 eingebe...
Mein Problem liegt in dem hervorgehobenen Bereich, davor sind die Zahlen in $_[0] zweimal, die sollen in $line mit einem Format geschrieben werden.
allerdings killt er nach Durchlauf des 0. Zyklus die 59 in $line, warum?
Danach läuft es ja, wie gewollt...

bin dankbar für jede Hilfe

MfG
Rahul
 

Anhänge

  • 25192attachment.zip
    3,9 KB · Aufrufe: 19
Zuletzt bearbeitet:
Also ich haber mich mal heute wieder dran gesetzt und ein einfaches Vorziehen der my- Funktion aus der Schleife löst das Problem *Freu*.
Also im Prinzip so:
Code:
    86       my $line;
     87     for (my $ctr1=1; $ctr1 < $NumofNum; $ctr1++){
     88         $line=" " if (($ctr1-1)%15==0||$ctr1==1);
Wenn mir jemand das noch erklären könnte, wäre ich natürlich dankbar...
Ansonsten auch gut,
schöne Tage noch

Rahul
 
Zuletzt bearbeitet:
Hallo Rahul0891!

Der Fehler ist da relativ einfach erklärt. ;)
Du deklarierst die Variable ja nur in einigen bestimmten Fällen:
Perl:
my $line=" " if (($ctr1-1)%15==0||$ctr1==1);
Das geschieht hier durch die nachgestellte if-Bedienung. Trifft diese nun nicht zu, bleibt $line leer. Wird jetzt im weiteren Schleifendurchlauf auch nichts in $line eingetragen, so wird beim versuch von
Perl:
print $line;
natürlich versucht eine nicht initialisierte Variable auszugeben. Und das führt in Perl zu dieser Warnung die du gesehen hast.

Wenn du jetzt natürlich die Deklaration vor die Schleife setzt, umgehst du das Problem, da die Variable ja immer mit sicherheit gesetzt ist. Allerdings verlierst du so auch die Vorteile von Lokalem Scoping. Also bei mehreren Schleifendurchläufen behält die Variable $line jetzt ihren alten Wert.

Besser wäre es, wenn du einfach das "my $line;" innerhalb der for-Schleife an den Anfang alleine schreibst und dann nur das Anhängen eines Leerzeichens von eine Bedienung abhängig machst:

Perl:
for (my $ctr1=1; $ctr1 < $NumofNum; $ctr1++){
     my $line;
     $line=" " if (($ctr1-1)%15==0||$ctr1==1);
     [...]
}

Hoffe geholfen zu haben.

Gruß,
Sven
 

Neue Beiträge

Zurück