2

使用Microsoft COBOL 编译器 2.2 版,我的代码完全可以正常工作。

   IDENTIFICATION DIVISION.
   PROGRAM-ID. COCENTRY.
   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
       SELECT COC-FILE
         ASSIGN TO DISK
         ORGANIZATION IS INDEXED
         ACCESS MODE IS RANDOM
         RECORD KEY IS COCNO
           FILE STATUS IS FILE-STATUS.
   DATA DIVISION.
   FILE SECTION.
   FD  COC-FILE LABEL RECORD IS STANDARD
       VALUE OF FILE-ID IS "COC.DAT".
   01  COC-RECORD.
       03  COCNO            PIC 9(5).
       03  COCDESC          PIC X(40).
   WORKING-STORAGE SECTION.
   01  FILE-STATUS  PIC XX.
   01  ESC-CODE PIC 99 VALUE 0.
       88  ESC-KEY  VALUE 1.
       88  F2       VALUE 3.
       88  F10      VALUE 11.
   01  ERRMSG       PIC X(70) VALUE SPACES.
   01  ERR          PIC 9 VALUE 0.
   SCREEN SECTION.
   01  FORM1.
       03 BLANK SCREEN BACKGROUND-COLOR 1.
       03 LINE 1 COLUMN 1 'COCNO'.
       03 LINE 2 COLUMN 1 'COCDESC'.
       03 LINE 24 COLUMN 1 "Esc=Exit  F2=Save  F10=Cancel".
       03 LINE 25 COLUMN 1 PIC X(70) FROM ERRMSG HIGHLIGHT.
   01  FORM2.
       03 LINE 1 COLUMN 14 PIC 9(5)
          USING COCNO REVERSE-VIDEO.
       03 LINE 2 COLUMN 14 PIC X(40)
          USING COCDESC REVERSE-VIDEO.
       03 LINE 24 COLUMN 1 PIC 99
          USING ESC-CODE.
   PROCEDURE DIVISION.
   MAIN.
       OPEN I-O COC-FILE.
       IF FILE-STATUS NOT = '00'
           OPEN OUTPUT COC-FILE
           CLOSE COC-FILE
           OPEN I-O COC-FILE.
       PERFORM ENTRY1 THRU ENTRYX UNTIL ESC-KEY.
       CLOSE COC-FILE.
       STOP RUN.
   ENTRY1.
       MOVE SPACES TO COC-RECORD.
       MOVE ZEROES TO COCNO.
   ENTRY2.
       DISPLAY FORM1 FORM2.
       ACCEPT FORM2.
       ACCEPT ESC-CODE FROM ESCAPE KEY.
       IF F10
           MOVE 'Entries canceled...' TO ERRMSG
           GO ENTRY1
       ELSE IF F2
           GO ENTRY3
       ELSE IF ESC-KEY
           GO ENTRYX
       ELSE
           GO ENTRY2.
   ENTRY3.
       MOVE 0 TO ERR.
       WRITE COC-RECORD INVALID KEY MOVE 1 TO ERR.
       IF ERR = 1
           MOVE 'Duplicate key not allowed...' TO ERRMSG
           GO ENTRY2
       ELSE
           MOVE 'Entries recorded...' TO ERRMSG
           GO ENTRY1.
   ENTRYX.
       EXIT.

现在我正在使用具有 GNUCobol 版本 1.1.0 的 OpenCobol IDE 4.3.0,并且我被提示这几行

syntax error, unexpected "Literal", expecting LEADING or TRAILING

 03 LINE 1 COLUMN 1 'COCNO'.
 03 LINE 2 COLUMN 1 'COCDESC'.
 03 LINE 24 COLUMN 1 "Esc=Exit  F2=Save  F10=Cancel".

所以我通过添加VALUE关键字来修复它们:

 03 LINE 1 COLUMN 1 VALUE 'COCNO'.
 03 LINE 2 COLUMN 1 VALUE 'COCDESC'.
 03 LINE 24 COLUMN 1 VALUE "Esc=Exit  F2=Save  F10=Cancel".

但是一旦我这样做,我就会得到另一个提示

'ACCEPT .. FROM ESCAPE KEY' not implemented

在这条线上

ACCEPT ESC-CODE FROM ESCAPE KEY.

这可能是什么原因?什么可以解决这个问题?

4

3 回答 3

4

您的实际答案在这里,https: //sourceforge.net/p/open-cobol/discussion/help/thread/26a01c5f/,在 SourceForge 的 GnuCOBOL 部分。VALUE如果您使用 GnuCOBOL 编译器的 2.0 版或更高版本,只需稍作更改,您的代码将“完全适用”您为包含该子句所做的更改。

您的代码可能“完全有效”,但它是意大利面条代码。

该术语来自过去,与程序中许多分支的使用有关,这是当时的一种常见做法,但这使得尝试遵循逻辑成为一个过程,就像试图遵循一条煮熟的意大利面条一样,它是一堆煮熟的意大利面。

如果你改变这个:

PERFORM ENTRY1 THRU ENTRYX UNTIL ESC-KEY.

对此:

PERFORM ENTRY1 THRU ENTRYX.

你的程序仍然可以工作。使困惑?是的,因为你有意大利面。您的程序流程只会到达 ENTRYX 一次。当它到达 ENTRYX 时的值是 ESC-KEY,但这是多余的,因为它只能到达那里一次,当它是 ESC-KEY 时。清除?不?因为你有意大利面。

这是你的逻辑,重写:

   PROCEDURE DIVISION.
       OPEN I-O COC-FILE
       IF FILE-STATUS NOT = '00'
           [the following code is a horror. Deal with this outside the 
           program. Crash for an unexpected FILE STATUS on OPEN]
           OPEN OUTPUT COC-FILE
           CLOSE COC-FILE
           OPEN I-O COC-FILE
       END-IF
       PERFORM PROCESS-USER-INPUT
         UNTIL ESC-KEY
       CLOSE COC-FILE
       IF FILE-STATUS NOT = '00'
           [something bad has happened, so don't go quietly]
       END-IF
       GOBACK
       .
   PROCESS-USER-INPUT.
       PERFORM BLANK-OUTPUT-RECORD
       PERFORM PROCESS-COC
         UNTIL ESC-KEY
       .
   PROCESS-COC.

       DISPLAY FORM1 FORM2
       ACCEPT FORM2
       ACCEPT ESC-CODE FROM ESCAPE KEY
       EVALUATE TRUE
         WHEN F10
           MOVE 'Entries canceled...' TO ERRMSG
         WHEN F2
           PERFORM CREATE-OUTPUT
       END-EVALUATE
       .
   CREATE-OUTPUT.
       WRITE COC-RECORD 
       IF ATTEMPT-TO-WRITE-DUPLICATE [22 on the FILE STATUS field]
           MOVE 'Duplicate key not allowed...' TO ERRMSG
       ELSE
           MOVE 'Entries recorded...' TO ERRMSG
           PERFORM BLANK-OUTPUT-RECORD
       END-IF
       .
   BLANK-OUTPUT-RECORD.
       MOVE SPACES TO COC-RECORD
       MOVE ZEROES TO COCNO
       .

这会让你的程序看起来更简单吗?当别人看到它时(或者当你在两周内看到它时)更容易跟随、改变和理解它的作用?

还有其他事情,比如为什么将 COC-RECORD 设置为空格,然后将 COCNO 设置为零?将空格移至 COCDESC。

使您的数据/过程名称良好且具有描述性。FILE STATUS 有一个好名字(不要称它为 FILE-STATUS),当你有多个文件时,每个文件一个。仅在必要时使用句号/句点,并为您使用的所有条件结构使用范围分隔符。对所有 IO 使用 FILE STATUS 检查,不要在 IO 上使用曲折的 AT。

如果您现在看,程序中的第一个代码很长,只执行一次,并且(应该)与程序的业务功能无关。所以把所有这些都写在一个段落中,然后执行。结束时也一样。然后,您可以在启动和关闭时拥有尽可能多的代码,而不会使您的程序更难以遵循。

于 2015-02-16T00:58:24.270 回答
3

屏幕和键盘 I/O 是 MicroSoft Cobol 特有的风格。您可能需要稍微调整一下以使其与 OpenCobol 一起使用。

于 2015-02-15T15:21:35.360 回答
0
PROCEDURE DIVISION.
           SET ENVIRONMENT 'COB_SCREEN_EXCEPTIONS' TO 'Y'.
           SET ENVIRONMENT 'COB_SCREEN_ESC'        TO 'Y'.
  • 逃生:IF cob-crt-status = 2005……
  • 输入:IF cob-crt-status = 0........
  • F1:IF cob-crt-status = 1001……
  • F2:IF cob-crt-status = 1002……
于 2016-10-06T14:09:05.610 回答