COBOL计划不会结束

时间:2017-04-23 20:05:15

标签: cobol gnucobol

我目前正在编写一个带有屏幕的COBOL程序,该程序会检查并显示文件中的记录。但是,当我尝试输入除" F"以外的命令时,程序仍然卡住了。或" Q"。虽然它假设显示一个带有错误消息的新屏幕。我试图调用的错误消息是"<>"

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.

1 个答案:

答案 0 :(得分:1)

也许这可能更容易阅读和调试:

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

(我添加了行号以便于参考。)

这就是发生的事情:你错过了一个结局 - 如果在某个地方。

你可能在第28行之后错过了一个,但那不是问题所在。由于第7行的else已经有if(第11行),else将从第7行终止if并在线申请end-if 6.

我相信你在第31行之后错过了另一个move。目前发生的事情是,如果你输入 Q F 以外的其他内容,它会第4行的else,然后跳过第5行ifend-if终止时的所有内容。因为您在第31行之后错过了end-perform,所以它会跳过第38行的accept

一点澄清:如果您输入 Q F 以外的其他内容,它会进入无限循环的原因是它正在跳过res2 = "q" or "Q"在线34因此你没有机会输入任何其他东西。而且因为你的表演一直持续到a = " ",显然不是这样,所以它会永远循环。

这就是为什么适当的缩进非常必要的原因。一旦我缩进了一切,很明显问题是什么。你可以随便在每个方向输入内容,但是如果其他人必须稍后再来这个并且你可以让他们很快就讨厌你。如果它整洁清晰,他们会爱你。

此外,我注意到您为退出查找定义了88个级别,但您不使用它们。它们会使您的代码更具可读性。第7行和第7行的if res1 = spaces等测试使用graceful-fs可以简化8(假设OpenCOBOL以它应该的方式工作;我没有使用它。)

希望这有帮助。