2017-04-23 4 views
0

Ich schreibe gerade ein COBOL-Programm mit einem Bildschirm, der einen Datensatz aus einer Datei prüft und anzeigt. Das Programm bleibt jedoch hängen, wenn ich versuche, einen anderen Befehl als "F" oder "Q" einzugeben. Während es annimmt, wird mit einer Fehlernachricht Fehlermeldung einen neuen Bildschirm anzuzeigen, die ich zu berufen bin versucht, ist „<>“COBOL-Programm wird nicht beendet

Identification Division. 
    Program-ID.  Lab10b. 

    Environment Division. 
    Input-Output Section. 
    File-Control. 
     Select InFile Assign to "Lab10b-master.dat" 
     Organization is Indexed 
     Access Mode is Random 
     Record Key is Movie-Key 
     Status is FileStatus. 

    Data Division. 
    File Section. 
    FD InFile. 
    01 Movie. 
     05 Movie-Key  Pic 9(5). 
     05 Movie-Title  Pic X(50). 
     05 Movie-Genre  Pic X(20). 

    Working-Storage Section. 
    01 black constant as 0. 
    01 blue constant as 1. 
    01 green constant as 2. 
    01 cyan constant as 3. 
    01 red  constant as 4. 
    01 magenta constant as 5. 
    01 brown constant as 6. 
    01 white constant as 7. 
    01 Today-Date. 
     05 YYYY    Pic 9(4). 
     05 MM     Pic 9(2). 
     05 DD     Pic 9(2). 
    01 FileStatus    Pic 99. 
    01 Error-Message   Pic X(50). 
    01 Res1. 
     05 a     Pic X. 
     05 b     Pic X. 
     05 c     Pic X. 
     05 d     Pic X. 
     05 e     Pic X. 
    01 Res2     Pic X. 
     88 Quit  Value "Q" "q". 
     88 Find  Value "F" "f". 

    Screen Section. 
    01 data-screen. 
     05 screen-header. 
      10 PH-Month Blank Screen Line 01 Col 01 Pic Z9/ From MM. 
      10 PH-Day Line 01 Col 04 Pic 99/ From DD. 
      10 PH-Year Line 01 Col 07 Pic 9999 From YYYY. 
      10 Value "Stomper & Wombat's Movie Warehouse" 
      Line 01 Col 40. 
     05 screen-data. 
      10 Value "Movie #:  " Line 05 Col 9. 
      10 Movie-Number-Out Line 05 Col 24 
      Pic 9(5) from Movie-Key Blank When Zero. 
      10 Value "Title:   " Line 06 Col 9. 
      10 Movie-Title-Out Line 06 Col 24 
      Pic X(50) From Movie-Title. 
      10 Value "Genre:   " Line 07 Col 9. 
      10 Movie-Genre-Out Line 07 Col 24 
      Pic X(50) From Movie-Genre. 
     05 Error-Message-Out Line 11 Col 15 Pic X(50) 
      From Error-Message foreground-color red. 
     05 screen-response. 
      10 Value "Key:   [" Line 13 Col 9. 
      10 Key-Response Line 13 Col 25 Pic X(5) to Res1. 
      10 Value "]" Line 13 Col 30. 
     05 screen-response2. 
      10 Value "Command:  [" Line 14 Col 9. 
      10 Command-response Line 14 Col 25 Pic X to Res2. 
      10 Value "]" Line 14 Col 26. 


    Procedure Division. 
    000-Main. 
     Accept Today-Date From Date YYYYMMDD 
     Move YYYY To PH-Year 
     Move MM To PH-Month 
     Move DD To PH-Day 

     Open Input InFile 
     Move " " to Error-Message 
     Display data-screen 
     Accept screen-response2 
     If Res2 = "F" Or "f" 
      Accept screen-response 
     End-If 

     Perform Until res2 = "q" or "Q" 
      Move " " to Error-Message 
      If res2 <> "Q" And "q" and "f" and "F" *> If Command Response is not valid, Write this error message. 
      Move "<<Command Invalid>>" to Error-Message 
      Else if res2 = "f" Or "F" *> If command = find 
      If a = " " And b = " " And c = " " And d = " " 
      And e = " " *> Check if key is empty 
       Move "<<Key Must Be Provided>>" to Error-Message 
       Move " " to Movie 
      Else If (a = " " Or b = " " Or c = " " Or d = " " 
      Or e = " ") Or res1 is not numeric *> Check if key is numeric and complete? 
       Move "<<Invalid Key>>" to Error-Message 
       Move " " to Movie 
      Else 
       Move res1 to Movie-Key 
       Read InFile 
       Evaluate FileStatus 
        When 00 
         Continue 
        When 23 
         Move " " to Movie 
         Move "<<Key Not Found>>" to Error-Message 
        When Other 
         Move "<<Unknown Read Error>>" to Error-Message 
       End-Evaluate 
      End-If 
      Else 
      Continue 
      End-If 

      Display data-screen 
      Accept screen-response2 
      If Res2 = "F" Or "f" 
      Accept screen-response 
      End-If 
     End-Perform 

     Close InFile 
     Stop Run. 
+3

In Ihrem PERFORM haben Sie vier IFs und drei END-IFs. Ihr Code wird nicht ausgeführt, wie Sie es für richtig halten. –

+2

Wenn sich der Code "seltsam" verhält: kompilieren Sie ihn mit '-Wall' und wenn dies nicht wichtig ist, kompilieren Sie ihn mit' -W' neu. Abhängig von der Version von "cobc", die Sie verwenden, wird Ihnen eine "IF-Anweisung, die nicht von END-IF beendet wurde" zweimal angezeigt. –

+1

@SimonSobisch ja, ich habe den letzten verpasst :-) –

Antwort

1

Vielleicht könnte dies leichter zu lesen und zu debuggen:

01 Perform Until res2 = "q" or "Q" 
02  Move " " to Error-Message 
03  If res2 <> "Q" And "q" and "f" and "F" 
04   Move "<<Command Invalid>>"     to Error-Message 
05  Else 
06   if res2 = "f" Or "F" 
07   If a = " " And b = " " And c = " " And d = " " And 
08    e = " " *> Check if key is empty 
09    Move "<<Key Must Be Provided>>"  to Error-Message 
10    Move " "        to Movie 
11   Else 
12    If (a = " " Or b = " " Or c = " " Or d = " " 
13     Or e = " ") Or res1 is not numeric 
14     Move "<<Invalid Key>>"   to Error-Message 
15     Move " "       to Movie 
16    Else 
17     Move res1       to Movie-Key 
18     Read InFile 
19     Evaluate FileStatus 
20     When 00 
21      Continue 
22     When 23 
23      Move " "      to Movie 
24      Move "<<Key Not Found>>"  to Error-Message 
25     When Other 
26      Move "<<Unknown Read Error>>" to Error-Message 
27     End-Evaluate 
28    End-If 
29   Else 
30   Continue 
31   End-If 
32 
33  Display data-screen 
34  Accept screen-response2 
35  If Res2 = "F" Or "f" 
36   Accept screen-response 
37  End-If 
38 End-Perform 

(Ich habe Zeilennummern für einfache Referenz hinzugefügt.)

Hier ist was passiert: Sie verpassen ein Ende-wenn da irgendwo.

Vermutlich fehlt Ihnen eine nach Zeile 28, aber das ist nicht das Problem. Da Sie bereits ein else (in Zeile 11) für die if auf Linie 7 hatte, wird die else die if aus der Leitung 7 beenden und mit der auf Linie anwenden 6.

Ich glaube, du bist eine andere end-if nach Zeile fehlt 31. Was ist zur Zeit passiert, ist, dass, wenn Sie etwas anderes als Q eingeben und F, die move in Zeile 4, tut und dann springt alles zwischen den else in Zeile 5, und wenn die if beendet. Da Sie die end-if nach Zeile 31 fehlt, überspringt er alles bis zum end-perform auf Linie bis 38.

Eine kleine Klarstellung: Der Grund, warum es in eine Endlosschleife geht, wenn Sie etwas anderes als Q oder F eingeben ist, dass es die accept Zeile 34 überspringt und Sie somit keine Gelegenheit haben, etwas anderes einzugeben. Und weil deine Performance bis res2 = "q" or "Q" weitergeht, was es eindeutig nicht ist, wird es einfach für immer weiterlaufen.

Aus diesem Grund ist eine korrekte Einrückung sehr notwendig. Sobald ich alles eingerückt hatte, war es offensichtlich, was das Problem war. Es kann für dich in Ordnung sein, einfach Sachen in alle Richtungen zu tippen, aber wenn jemand später mitkommen und daran arbeiten muss, wirst du sie sehr schnell hassen. Wenn es sauber und klar ist, werden sie dich lieben.

Auch ich bemerken Sie 88 Ebenen für definiert haben Quit und finden, aber Sie verwenden sie nicht. Sie würden Ihren Code viel lesbarer machen. Und die Tests mit a = " " usw. auf den Leitungen 7 & 8 könnten durch die Verwendung if res1 = spaces vereinfacht werden (unter der Annahme, OpenCOBOL so funktioniert, wie es sollte;. Ich kann es nicht benutzt habe)

Hoffnung, das hilft.

Verwandte Themen