Cobol “接受”的麻烦;ESC-退出键的代码“;

Cobol “接受”的麻烦;ESC-退出键的代码“;,cobol,gnucobol,Cobol,Gnucobol,使用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

使用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,并且有以下几行提示

语法错误,意外的“文字”,应为前导或尾随

 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 1 COLUMN 1 VALUE 'COCNO'.
 03 LINE 2 COLUMN 1 VALUE 'COCDESC'.
 03 LINE 24 COLUMN 1 VALUE "Esc=Exit  F2=Save  F10=Cancel".
但一旦我这样做,我就会得到另一个提示

“接受…”。。“退出键”未执行

在这条线上

从退出键接受ESC-code。


可能的原因是什么?有什么办法可以解决这个问题呢?

屏幕和键盘I/O是微软Cobol特有的风格。您可能需要对其进行一些调整,以使其与OpenCobol一起工作。

您的实际答案在这里,位于SourceForge的GnuCOBOL部分。如果您使用的是2.0版或更高版本的GnuCOBOL编译器,那么只要稍作修改,您的代码就可以“完全工作”在您已经做出的修改中,包括
VALUE
子句

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

这个术语来源于古代,涉及到在程序中使用许多分支,这在当时是一种常见的做法,但这使得试图遵循逻辑的过程就像试图遵循一堆熟意大利面中的一条熟意大利面

如果您更改此选项:

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

使您的数据/过程名称具有良好的描述性。文件状态有一个好的名称(不要称之为文件状态),当您有多个文件时,每个文件一个。仅在必要时使用句号/句点,并对所有使用的条件构造使用范围分隔符。对所有IO使用文件状态检查,不要在IO上使用迂回的AT

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

PROCEDURE DIVISION.
           SET ENVIRONMENT 'COB_SCREEN_EXCEPTIONS' TO 'Y'.
           SET ENVIRONMENT 'COB_SCREEN_ESC'        TO 'Y'.
  • 转义:
    如果cob crt状态=2005
  • 输入:
    如果cob crt状态=0
  • F1:
    如果cob crt状态=1001
  • F2:
    如果cob crt状态=1002

您好,谢谢您的光临,先生,您有更简洁的回答吗?像代码之类的?那会更好,因为我还是COBOL新手。非常感谢。干杯我能推荐的最好的方法是程序员指南:屏幕I/O在不同的编译器之间是不同的,所以当你移动时,它会涉及到一定程度的重新编码。是的,先生,我也在GnuCOBOL论坛上发布了这篇文章,非常感谢你的帮助。我会尝试一下,完成后会回复你。你能为你的答案添加一些解释吗?只有张贴代码可能会让一些人感到困惑。