【问题标题】:Reading a table from a file only results in the first record being stored从文件中读取表只会导致存储第一条记录
【发布时间】:2020-09-22 03:22:00
【问题描述】:

附加背景:这是Adding two integers giving unwanted result in cobol 的后续。

由于输入数据由字符串组成,计算需要整数,因此该程序批量读取每一行,然后从文件中单独读取每个字段,并将必要的字段转换为数字,然后将它们存储在工作存储部分表中。

现在,由于某种原因,只有第一条记录可以正确读取和存储。我猜其余的记录被读取为空白或空值,即使第一条记录之后的文件内容显然不为空。

这是我当前的完整程序代码:

    IDENTIFICATION DIVISION.
    PROGRAM-ID. GRADEREPORT.
    AUTHOR. JORDAN RENAUD.
    DATE-WRITTEN. 09/18/2020.
    
    ENVIRONMENT DIVISION.
    INPUT-OUTPUT SECTION.
    FILE-CONTROL.
           SELECT GRADES-FILE ASSIGN TO "bill"
               ORGANIZATION IS LINE SEQUENTIAL
               ACCESS IS SEQUENTIAL.
    
    DATA DIVISION.
    FILE SECTION.
    FD GRADES-FILE.
    01     INPUT-TOTAL-POINTS       PIC 9(4).
    01     INPUT-GRADES.
    05         INPUT-GRADE OCCURS 1 to 100 TIMES DEPENDING ON RECORD-COUNT.
    10            INPUT-ASSIGNMENT-NAME   PIC X(20).
    10            INPUT-CATEGORY          PIC X(20).
    10            INPUT-POINTS-POSSIBLE   PIC X(14).
    10            INPUT-POINTS-EARNED     PIC X(14).
    
    WORKING-STORAGE SECTION.
    77     GRADES-FILE-EOF          PIC 9.
    01     RECORD-COUNT             PIC 9(8) VALUE 0.
    01     TOTAL-EARNED-POINTS      PIC 9(14) VALUE ZERO.
    01     TOTAL-POSSIBLE-POINTS    PIC 9(14) VALUE 5.
    01     K                        PIC 9(14) VALUE 1.
    01     TMP                      PIC 9(14).
    01     CURRENT-CATEGORY         PIC X(20).
    01     CATEGORY-WEIGHT          PIC X(3).
    01     LAST-CATEGORY            PIC X(20).
    01     TOTAL-POINTS             PIC 9(4).
    01     GRADES.
    05         GRADE OCCURS 1 TO 100 TIMES DEPENDING ON RECORD-COUNT.
    10            ASSIGNMENT-NAME   PIC X(20).
    10            CATEGORY          PIC X(20).
    10            POINTS-POSSIBLE   PIC 9(14).
    10            POINTS-EARNED     PIC 9(14).
    
    PROCEDURE DIVISION.
           OPEN INPUT GRADES-FILE.
           READ GRADES-FILE INTO TOTAL-POINTS.
           DISPLAY TOTAL-EARNED-POINTS
           PERFORM UNTIL GRADES-FILE-EOF = 1
               READ GRADES-FILE
                  AT END SET
                  GRADES-FILE-EOF TO 1
                  NOT AT END
                     ADD 1 TO RECORD-COUNT
    
                     MOVE INPUT-ASSIGNMENT-NAME(RECORD-COUNT) TO ASSIGNMENT-NAME(RECORD-COUNT)
                     DISPLAY INPUT-ASSIGNMENT-NAME(RECORD-COUNT)
                     DISPLAY ASSIGNMENT-NAME(RECORD-COUNT)
    
                     MOVE INPUT-CATEGORY(RECORD-COUNT) TO CATEGORY(RECORD-COUNT)
                     DISPLAY INPUT-CATEGORY(RECORD-COUNT)
                     DISPLAY CATEGORY(RECORD-COUNT)
    
                     MOVE FUNCTION NUMVAL (INPUT-POINTS-POSSIBLE(RECORD-COUNT)) TO POINTS-POSSIBLE(RECORD-COUNT)
                     DISPLAY INPUT-POINTS-POSSIBLE(RECORD-COUNT)
                     DISPLAY POINTS-POSSIBLE(RECORD-COUNT)
    
                     MOVE FUNCTION NUMVAL (INPUT-POINTS-EARNED(RECORD-COUNT)) TO POINTS-EARNED(RECORD-COUNT)
                     DISPLAY INPUT-POINTS-EARNED(RECORD-COUNT)
                     DISPLAY POINTS-EARNED(RECORD-COUNT)
    
                     COMPUTE TOTAL-EARNED-POINTS = TOTAL-EARNED-POINTS + POINTS-EARNED(RECORD-COUNT)
                     DISPLAY TOTAL-EARNED-POINTS
               END-READ
           END-PERFORM.
           CLOSE GRADES-FILE.
           DISPLAY TOTAL-EARNED-POINTS.
           SORT GRADE ASCENDING CATEGORY.
           MOVE CATEGORY(1) TO LAST-CATEGORY.
           PERFORM RECORD-COUNT TIMES
               MOVE CATEGORY(K) TO CURRENT-CATEGORY
               IF CURRENT-CATEGORY = LAST-CATEGORY THEN
                  DISPLAY "SAME CATEGORY"
               ELSE
                  DISPLAY "NEW CATEGORY"
                  MOVE LAST-CATEGORY TO CURRENT-CATEGORY
               END-IF
               SET K UP BY 1
           END-PERFORM
           DISPLAY GRADES.
           STOP RUN.

这里是输入文件,bill:

1000
MS 1 - Join Grps    Group Project       5             5             
Four Programs       Programming         15            9             
Quiz 1              Quizzes             10            7             
FORTRAN             Programming         25            18            
Quiz 2              Quizzes             10            9             
HW 1 - Looplang     Homework            20            15            

根据编写的代码,从文件的表部分读取的第一行(第 2 行和前行)具有其各个部分 DISPLAY ,如下所示:

MS 1 - Join Grps    
MS 1 - Join Grps    
Group Project       
Group Project       
5             
00000000000005
5             
00000000000005

这是我所期望的。每一项都是重复的,第一次迭代是输入文件结构,第二次是工作存储节结构。不同之处在于输入结构被读取为所有长度为 20 和 14 的字符串,存储结构被格式化为两个长度为 20 的字符串和两个长度为 14 的整数。如前所述,数字字符串被转换为整数并存储在工作存储中。 第二行 DISPLAY 的输出显示如下:

00000000000000
              
00000000000000
00000000000005
                    
                    
                    
                    
              
00000000000000
              
00000000000000
00000000000005
                    
                    
                    
                    
              
00000000000000
              
00000000000000
00000000000005
                    
                    
                    
                    
              
00000000000000
              
00000000000000
00000000000005
                    
                    
                    
                    
              
00000000000000
              
00000000000000
00000000000005

在这种情况下,00000000000005 是求和累加器变量的总和,它始终为 5,因为第一行读取 5 表示获得的积分,其余的只是评估为零,因为它们正在读作空格。

如何让我的程序正确读取文件的其余部分?

【问题讨论】:

  • 出于兴趣:-debug 不引发异常?快速浏览一下,您可能想要从输入文件中删除 ODO (OCCURS DEPENDIG ON)。而且您可能希望使用EXIT PERFORM 而不是设置然后检查eof 变量和/或将代码拆分为SECTIONs(或仅前cobol85 样式的段落)以提高可读性(但这更像是一种样式问题,所以只是一个注释)。如果您自己操作,请自行回答(Q&A-stye),否则请在编辑后留言。
  • 注意:我已经编辑了您的问题以遵循 SO 规则,请查看编辑。我们可以通过 cmets 聊天也被自动“清理”,除了投票赞成的 cmets [这些旨在“提供对问题/答案的洞察”] 或通过讨论板。另请注意:最好将其作为附加问题发布,并且您的问题显示研究,因此它们在这里完美匹配。
  • 感谢您的洞察和编辑,这些都是我可以做的,但我唯一真正的目标是拥有一个工作程序,它接受定义的输入,并返回定义的输出报告。基本上,在这门编程语言课程中,我们被分配了小组和一个名为“四个程序”的作业。首先,我们可以用任何我们想要的语言来实现它们。然后我们必须在 Fortran 66 (IV) 中进行,现在是 Cobol。因此,了解获得所需输出所需的算法更少,更多的是弄清楚如何在不同语言中实现相同的算法,并观察语言如何
  • (2)你正在编写的程序可以简化这个过程。
  • 哦,回答您的问题,将 -debug 标志添加到我的 launch.json 并没有真正对控制台输出产生影响。我正在使用调试器(第一次真正使用调试器)进行单步调试,但它仍然无助于找出为什么它没有像我想要的那样读取整个内容。

标签: cobol gnucobol


【解决方案1】:

事实证明,当从文件中读取表时,访问当前行的下标始终为 1,因此我没有将 RECORD-COUNT 作为 INPUT-items 的下标读取,而是将它们全部设置为 1,程序按预期运行!

【讨论】:

  • 该文件只有一个“光学”表。请记住,READ 将读取一行并将其放入您告诉它的记录中。这些记录中的每一个都是光学表的一个条目,因此您可能会完全删除OCCURS。对于 SO 中的一个很好的问答,我建议使用更新的代码(部分)以及您的解释来编辑您的答案,并“接受”您的答案为“对我有用”。
  • 是的,我必须等待 21 小时才能接受自己的答案,我仍在等待,但稍后我不工作时会编辑。
  • ping 以接受答案(问题当前显示为“已回答但未解决”)
猜你喜欢
  • 2015-09-06
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 2021-08-29
相关资源
最近更新 更多