【问题标题】:COBOL program won't endCOBOL 程序不会结束
【发布时间】:2017-04-23 20:05:14
【问题描述】:

我目前正在编写一个带有屏幕的 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.

【问题讨论】:

  • 在您的 PERFORM 中,您有四个 IF 和三个 END-IF。你的代码不会像你想象的那样执行。
  • 如果代码表现“奇怪”:使用-Wall 重新编译,如果这没有显示任何重要的内容,使用-W 重新编译。根据 cobc 的版本,您使用其中之一将显示“IF 语句未由 END-IF 终止”2 次。
  • @SimonSobisch 是的,我错过了最后一个 :-)

标签: cobol gnucobol


【解决方案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

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

这就是发生的事情:你在某处错过了一个 end-if。

您可能在第 28 行之后错过了一个,但这不是问题所在。因为您已经为第 7 行的 if 提供了一个 else(第 11 行),所以 else 将从第 7 行终止 if 并应用于第 6 行的那个。

我相信您在第 31 行之后缺少另一个 end-if。目前发生的情况是,如果您输入 QF 以外的其他内容,它会执行 @第 4 行的 987654327@,然后跳过第 5 行的 elseif 终止之间的所有内容。因为您在第 31 行之后缺少 end-if,所以它会跳过所有内容,直到第 38 行的 end-perform

稍微澄清一下:如果您输入 QF 以外的其他内容,它会进入无限循环的原因是它跳过了第 34 行的 accept 和因此您没有机会输入其他任何内容。而且因为你的表演一直持续到res2 = "q" or "Q",它显然不是,它会一直循环下去。

这就是为什么正确的缩进是非常必要的。一旦我缩进了所有内容,问题就很明显了。你可以随便输入一些东西,但如果其他人必须稍后来处理这个问题,你会让他们很快讨厌你。如果它整洁清晰,他们会爱你的。

另外,我注意到您为 QuitFind 定义了 88 个级别,但您不使用它们。它们将使您的代码更具可读性。在第 7 行和第 8 行使用 a = " " 等进行的测试可以通过使用 if res1 = spaces 来简化(假设 OpenCOBOL 可以正常工作;我没有使用过。)

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    相关资源
    最近更新 更多