COBOL仅从一个输入文件读取一行

3

有一个 Cobol 批处理程序的问题,它只从输入文件中读取一行数据,而且被读取的那行不是第一行。输入文件的记录是固定长度的。

以下是代码:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. AverageGPA. 
       ENVIRONMENT DIVISION. 
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
          SELECT STUDENT-DATA
             ASSIGN TO "C:\COBOL\CH0708.DAT"
             ORGANIZATION IS LINE SEQUENTIAL.        
          SELECT OUTPUT-FILE
             ASSIGN TO "C:\COBOL\STUDENT_GPA.DAT"
             ORGANIZATION IS LINE SEQUENTIAL. 
       DATA DIVISION. 
       FILE SECTION.
       FD  STUDENT-DATA.
       01  EMPLOYEE-RECORD.
           05  SSN-IN                PICTURE X(9).
           05  NAME-IN               PICTURE X(21). 
           05  CLASS-IN              PICTURE 9.    
           05  SCHOOL-IN             PICTURE 9.
           05  GPA-IN                PICTURE 9V99.
           05  CREDITS-IN            PICTURE 999.
       FD  OUTPUT-FILE. 
       01  OUTPUT-DATA. 
           05  SSN-OUT               PICTURE X(9).  
           05                        PICTURE X(5).
           05  NAME-OUT              PICTURE X(21).
           05  CLASS-OUT             PICTURE X(9).
           05                        PICTURE X(5).
           05  SCHOOL-OUT            PICTURE X(15).
           05                        PICTURE X(5).
           05  GPA-OUT               PICTURE 9.99.
           05                        PICTURE X(5).
           05  CREDITS-OUT           PICTURE Z99.
       WORKING-STORAGE SECTION.
       01  OUTPUT-HEADING.
           05 SSN-HEADING            PICTURE X(9) 
                                        VALUE 'SSN'.
           05                        PICTURE X(5).
           05 NAME-HEADING           PICTURE X(21) 
                                        VALUE 'STUDENT NAME'.
           05 CLASS-HEADING          PICTURE X(9) VALUE 'CLASS'.
           05                        PICTURE X(5).
           05 SCHOOL-HEADING         PICTURE X(15) VALUE 'SCHOOL'.
           05                        PICTURE X(5).
           05 GPA-HEADING            PICTURE X(3) VALUE 'GPA'.
           05                        PICTURE X(5).
           05 CREDITS-HEADING        PICTURE X(7) VALUE 'CREDITS'.
       01  GPA-COUNT                 PICTURE 9 VALUE 0.
       01  GPA-SUM                   PICTURE 9V99 VALUE 0.
       01  AVERAGE-GPA               PICTURE 9.99.
       01  AVERAGE-GPA-LINE          PICTURE X(16)
                                VALUE 'AVERAGE GPA IS '.
       01  ARE-THERE-MORE-RECORDS    PICTURE XXX VALUE 'YES'.
       PROCEDURE DIVISION.
       100-MAIN-MODULE.
           OPEN INPUT STUDENT-DATA
                OUTPUT OUTPUT-FILE
           WRITE OUTPUT-DATA FROM OUTPUT-HEADING
           PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO '
              READ STUDENT-DATA
                  AT END
                      MOVE 'NO' TO ARE-THERE-MORE-RECORDS
                  NOT AT END
                      PERFORM 200-WRITE-GPA
                      
                 END-READ
           END-PERFORM
           DIVIDE GPA-SUM BY GPA-COUNT GIVING AVERAGE-GPA
           WRITE OUTPUT-DATA FROM AVERAGE-GPA-LINE
           WRITE OUTPUT-DATA FROM AVERAGE-GPA
           CLOSE STUDENT-DATA
                 OUTPUT-FILE
           STOP RUN.
       200-WRITE-GPA.
           MOVE SPACES TO OUTPUT-DATA.
           MOVE SSN-IN TO SSN-OUT
           MOVE NAME-IN TO NAME-OUT
           IF CLASS-IN = 1
              MOVE 'FRESHMAN' TO CLASS-OUT
           ELSE IF CLASS-IN = 2
              MOVE 'SOPHOMORE' TO CLASS-OUT
           ELSE IF CLASS-IN = 3
              MOVE 'JUNIOR' TO CLASS-OUT
           ELSE IF CLASS-IN = 4 
              MOVE 'SENIOR' TO CLASS-OUT
           ELSE
              MOVE CLASS-IN TO CLASS-OUT
           END-IF
           IF SCHOOL-IN = 1
              MOVE 'BUSINESS' TO SCHOOL-OUT
           ELSE IF SCHOOL-IN = 2
              MOVE 'LIBERAL ARTS' TO SCHOOL-OUT
           ELSE IF SCHOOL-IN = 3
              MOVE 'ENGINEERING' TO SCHOOL-OUT
           ELSE
              MOVE 'INVALID' TO SCHOOL-OUT
           END-IF
           MOVE GPA-IN TO GPA-OUT
           ADD  GPA-IN TO GPA-SUM
           MOVE CREDITS-IN TO CREDITS-OUT
           ADD 1 TO GPA-COUNT
           WRITE OUTPUT-DATA.
           STOP RUN.
标签中定义的文件是:
125997600R. HENDERSON         11379011
234789543P. MARTINSON         11250011
276888003M. JACKSON           22394020
332557267B. BRUHANSKY         21314020
235654654K. THOMPSON          23279021
336221180F. SMITH             21304019
332557845D. MIKA              33217024
377000854A. ABRAMS            31379027
399000002L. NAIRN             33375029
211311411P. BUTTRAM           41397035
122886567F. DARK              41297034
224257889S. SMITH             41397038
125654334C. HAYES             41400040
345345669J. FISHER            42200036
432234543S. JONES             43291033
488345612M. PILLION           41255034

给出的输出结果是:
SSN           STUDENT NAME         CLASS         SCHOOL              GPA     CRED
432234543     S. JONES             SENIOR        ENGINEERING         2.91      33
AVERAGE GPA IS
2.91

此外,还有两个问题。 为什么学分标题没有显示所有字母?如何设置平均GPA的行?目前它在两行上,但我想让它只有一行。

2
你的200-WRITE-GPA段落中有一个STOP RUN,因此它将在第一次执行该段落时停止执行。此外,你输出的名称(S> JONES)在你列出的输入中并不存在。你确定你展示给我们的是正确的文件吗? - NicC
这是正确的文件,是倒数第二行。至于STOP RUN,如果没有它,我会收到一个意外的文件结尾错误。 - nboz75
仍然只显示S. Jones行,不知何故。 - nboz75
1
在最后一行出现错误并不是在第一行执行 STOP RUN 的理由。 - user207421
这与Cobol无关,只是逻辑。 - user207421
显示剩余3条评论
1个回答

5
  • 为什么学分表头没有显示所有字母-输出记录不够长,无法容纳完整的表头,请参见扩展部分。
  • 如何为平均GPA添加一条线-读取整个文件中的GPA总和并除以记录数。

学分表头问题

输出记录被定义为


       01  OUTPUT-DATA. 
           05  SSN-OUT               PICTURE X(9).  
           05                        PICTURE X(5).
           05  NAME-OUT              PICTURE X(21).
           05  CLASS-OUT             PICTURE X(9).
           05                        PICTURE X(5).
           05  SCHOOL-OUT            PICTURE X(15).
           05                        PICTURE X(5).
           05  GPA-OUT               PICTURE 9.99.
           05                        PICTURE X(5).
           05  CREDITS-OUT           PICTURE Z99.

只需在末尾添加填充即可。
       01  OUTPUT-DATA. 
           05  SSN-OUT               PICTURE X(9).  
           05                        PICTURE X(5).
           05  NAME-OUT              PICTURE X(21).
           05  CLASS-OUT             PICTURE X(9).
           05                        PICTURE X(5).
           05  SCHOOL-OUT            PICTURE X(15).
           05                        PICTURE X(5).
           05  GPA-OUT               PICTURE 9.99.
           05                        PICTURE X(5).
           05  CREDITS-OUT           PICTURE Z99.
           05                        picture X(2).

个人意见是:

  • 将输出记录定义移至工作存储区
  • output-data定义为单个图像

即,

       01  OUTPUT-DATA               pic x(73).
       
       Woring storage.
       
       01  report-record.       
           05  SSN-OUT               PICTURE X(9).  
           05                        PICTURE X(5).
           05  NAME-OUT              PICTURE X(21).
           05  CLASS-OUT             PICTURE X(9).
           05                        PICTURE X(5).
           05  SCHOOL-OUT            PICTURE X(15).
           05                        PICTURE X(5).
           05  GPA-OUT               PICTURE 9.99.
           05                        PICTURE X(5).
           05  CREDITS-OUT           PICTURE Z99.
           05                        picture X(2).

其他问题

我将进行更改。

          ADD 1 TO GPA-COUNT
           WRITE OUTPUT-DATA.
           STOP RUN.

to

           ADD 1 TO GPA-COUNT
           WRITE OUTPUT-DATA.
       299-exit.
           exit.

单行输出

只需创建一个如下的记录:

      01  Summary-line
          03               PICTURE X(16)
                                VALUE 'AVERAGE GPA IS '.
          03  everage-gpa  picture 9.99.

仅写入一条记录

问题在于您没有结束您的 if 语句。

         IF SCHOOL-IN = 1
              MOVE 'BUSINESS' TO SCHOOL-OUT
           ELSE IF SCHOOL-IN = 2
              MOVE 'LIBERAL ARTS' TO SCHOOL-OUT
           ELSE IF SCHOOL-IN = 3
              MOVE 'ENGINEERING' TO SCHOOL-OUT
           ELSE
              MOVE 'INVALID' TO SCHOOL-OUT
           END-IF
           MOVE GPA-IN TO GPA-OUT
           ADD  GPA-IN TO GPA-SUM
           MOVE CREDITS-IN TO CREDITS-OUT
           ADD 1 TO GPA-COUNT
           WRITE OUTPUT-DATA.

end-if结束了一个if,即它实际上是指

         IF SCHOOL-IN = 1
              MOVE 'BUSINESS' TO SCHOOL-OUT
         ELSE
           IF SCHOOL-IN = 2
              MOVE 'LIBERAL ARTS' TO SCHOOL-OUT
           ELSE 
              IF SCHOOL-IN = 3
                 MOVE 'ENGINEERING' TO SCHOOL-OUT
              ELSE
                 MOVE 'INVALID' TO SCHOOL-OUT
              END-IF
              MOVE GPA-IN TO GPA-OUT
              ADD  GPA-IN TO GPA-SUM
              MOVE CREDITS-IN TO CREDITS-OUT
              ADD 1 TO GPA-COUNT
              WRITE OUTPUT-DATA.

WRITE OUTPUT-DATA.结束所有嵌套的if语句。

使用Evaluate

         evaluate true
         when SCHOOL-IN = 1
              MOVE 'BUSINESS' TO SCHOOL-OUT
         when SCHOOL-IN = 2
              MOVE 'LIBERAL ARTS' TO SCHOOL-OUT
         when SCHOOL-IN = 3
              MOVE 'ENGINEERING' TO SCHOOL-OUT
         when other
              MOVE 'INVALID' TO SCHOOL-OUT
         END-evaluate
         MOVE GPA-IN TO GPA-OUT
         ADD  GPA-IN TO GPA-SUM
         MOVE CREDITS-IN TO CREDITS-OUT
         ADD 1 TO GPA-COUNT
         WRITE OUTPUT-DATA.


同样适用于另一个if end-if块。

谢谢,这解决了信用部分的问题。这是一个问题解决了。至于输出如何存储,由于这是一门大学课程,所以我认为我必须按照教授所教的方式来做。 - nboz75
1
对于 平均GPA 你将需要通过文件循环。我会为此更新答案。 - Bruce Martin
1
添加了额外的部分。 - Bruce Martin
1
问题在于你使用了if - 每个if都需要一个end-if,应该使用evaluate。我会更新答案。 - Bruce Martin
非常感谢,已经解决了。之前不知道有“evaluate”这个函数,所以只用了“if”。 - nboz75
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接