顺序文件输出计算 GPA

Sequential file output computing GPA

我需要一些 COBOL 作业的帮助。我做了几次尝试,但它们似乎并没有像我希望的那样工作。

我需要编写一个程序来读取包含一些学生信息的输入文件,然后将其输出到终端和一个输出文件。

我还需要根据获得的小时数和质量分数来计算 GPA。

我目前在创建列 headers 以及添加值以获得累积值以获得 GPA 等方面遇到问题。我有输入文件和到目前为止附上的代码。

IDENTIFICATION DIVISION.
PROGRAM-ID. TEST3.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION. 
FILE-CONTROL.
    SELECT StudentFile ASSIGN TO "P2In.dat"
            ORGANIZATION IS LINE SEQUENTIAL.
    SELECT OutputFile ASSIGN TO "Report.dat"
            ORGANIZATION IS LINE SEQUENTIAL.


DATA DIVISION.
FILE SECTION.
FD StudentFile.

*>Student details will only be printed once
01 StudentDetails.
    05 STUDENT-NAME         PIC X(16).
    05 STUDENT-ID           PIC X(9).

*>Semester info that will be on one line and not repeated
01 SemesterDetails.
    05 SEMESTER             PIC X(9).

*> Details in the class that need to be seperate
01 ClassDetails.
    05 CLASS-NAME           PIC X(32).
    05 GRADE                PIC X(2).
    05 HOURS                PIC X(4).
    05 POINTS               PIC X(2).

 *>values that need to be calculated
 01 CalculatedValues.
    05 CUMULATIVE-GPA-IN    PIC 99v99 VALUE ZERO.
    05 CUMULATIVE-QP-IN     PIC 99v99 VALUE ZERO.
    05 CUMULATIVE-HOURS-IN  PIC 99v99 VALUE ZERO.

FD OutputFile.
01 PrintLine                    PIC X(70).

WORKING-STORAGE SECTION.

01 SWITCHES.
    05 EOF-SWITCH           PIC X VALUE "N".
01 COUNTERS.
    05 REC-COUNTER          PIC 9(3) VALUE 0.
01 CUMULATIVE.
    05 CUMULATIVE-QP        PIC ZZ.99.

PROCEDURE DIVISION.
*>main paragraph, everything starts here
Main.
    PERFORM Begin.
    PERFORM ProcessData.
    PERFORM PrintLines
            UNTIL EOF-SWITCH = "Y".

*>opening read
Begin.
    OPEN INPUT StudentFile
    OPEN OUTPUT OutputFile

    READ StudentFile
            AT END
                    MOVE "Y" TO EOF-SWITCH
            NOT AT END
                    COMPUTE REC-COUNTER = REC-COUNTER + 1
    END-READ.

ProcessData.
    READ StudentFile
    AT END
            MOVE "Y" TO EOF-SWITCH
    NOT AT END
            IF GRADE = 'A'
                    COMPUTE CUMULATIVE-QP = CUMULATIVE-QP + 4
            ELSE
            IF GRADE = 'B'
 COMPUTE CUMULATIVE-QP = CUMULATIVE-QP + 3
            ELSE
            IF GRADE = 'C'
                    COMPUTE CUMULATIVE-QP = CUMULATIVE-QP + 2
            ELSE
            IF GRADE = 'D'
                    COMPUTE CUMULATIVE-QP = CUMULATIVE-QP + 1
            END-IF.


*>printing out our lines to terminal
PrintLines.

    READ StudentFile
    AT END
            MOVE "Y" TO EOF-SWITCH

    NOT AT END
            DISPLAY CUMULATIVE-QP
    END-READ.

输入文件如下所示

TERRY ETHELBERT W1234567 FALL2014 CMPS161 ALGORITHM DSGN/IMPLMNT    A 3.00  12.00
TERRY ETHELBERT W1234567 FALL2014 CMPS280 ALGORITHM DSGN/IMPLMNTII  B 3.00  9.00
TERRY ETHELBERT W1234567 FALL2014 CMPS431 OPERATING SYSTEMS         C 3.00  6.00
TERRY ETHELBERT W1234567 FALL2014 ENG322  TECHNICAL WRITING         A 3.00  12.00
TERRY ETHELBERT W1234567 SPNG2015 MATH380 STATISTICS                B 3.00  9.00
TERRY ETHELBERT W1234567 SPNG2015 HIST202 HISTORY                   B 3.00  9.00
TERRY ETHELBERT W1234567 SPNG2015 BIOL152 GENERAL BIOLOGY           A 3.00  12.00
TERRY ETHELBERT W1234567 SPNG2015 MATH200 CALCULUS I                C 5.00  10.00    

最好有一个起点。

第一个问题是让您的输入记录正确。 FD 必须匹配行布局,所以它应该是这样的

01 StudentDetails.
    05 STUDENT-NAME         PIC X(16).
    05 STUDENT-ID           PIC X(9).
*> Details in the class that need to be seperate
*01 ClassDetails.
    05 CLASS-NAME           PIC X(32).
    05 GRADE                PIC X(1).
    05 FILLER               PIC X(1).
    05 HOURS.
       07 HOURS-9           PIC 9.99.
    05 FILLER               PIC X(2).
    05 POINTS.
       07 POINTS-X          PIC X(1) OCCURS 5.
    05 POINTS-9-99 REDEFINES POINTS.
       07 POINTS-9-99       PIC 9.99.
    05 POINTS-99-99 REDEFINES POINTS.
       07 POINTS-99-99      PIC 99.99.

请注意,GRADE 是一个 X(1),后面跟着一个 FILLER 也是 X(1),表示等级字母后面的 space。

HOURS 隐式为 X(4); HOURS-9 允许将该字段读取为 9.99

然后有2个spaces - 另一个filler

最后,有积分。这是一个 5 个字符的字段,有 2 个布局。我们通过查看 POINTS-X(2) 来确定使用哪个布局(POINTS-9-99 或 POINTS-99-99)——一个点表示使用 POINTS-9-99,否则使用 POINTS-99-99。

我不知道学期详情是什么。

您的计算值应该在工作存储中;你不能在 FD 中有 VALUE 子句。

接下来,您应该仔细考虑您的流程。想想迈克尔杰克逊。严重地。哦-不是歌手,是计算机科学家。

您的进程:

从包含 SPACESCURRENT-STUDENT 开始。

读取每条记录。如果 STUDENT-NAME 不等于 CURRENT-STUDENT(以及 AT END),则(生成报告行,将累加器归零并将 STUDENT-NAME 存储到 CURRENT-STUDENT。)并使用当前记录中的字段来累加所需数据。

请注意,生成报告行只是将各种累积字段构建到输出记录中并进行一些数学体操以计算平均值的问题。当然,如果 CURRENT-STUDENT 包含 SPACES,请不要打扰。

所以,要点是

READ studentfile
  at end perform write-report-line
  not at end 
      if student-name is not equal to current-student
            perform write-report-line
      end-if
      perform accumulate-data.

write-report-line 段是

if current-student is not equal to spaces
   calculate and move name, average, etc. to output-record 
   and write it
end-if
move student-name to current-student
move zero to rec-counter etc, etc.

正如 Magoo 所指出的,您需要弄清楚您的记录定义。当您将每个逻辑块定义为单独的 01 级别时,您定义了单独的记录。这与您的数据不匹配(目前我们假设它是正确的)。不清楚什么是 POINTS,但您的定义与数据不符。

01 RecordDetails.
  03 StudentDetails.
    05 STUDENT-NAME         PIC X(16).
    05 STUDENT-ID           PIC X(9).
  03 SemesterDetails.
    05 SEMESTER             PIC X(9).
  03 ClassDetails.
    05 CLASS-NAME           PIC X(32).
    05 GRADE                PIC X(2).
    05 HOURS                PIC X(4).
    05 POINTS               PIC X(2).

这个你已经定义为从属于 FD,所以它作为你文件中的记录:

 01 CalculatedValues.
    05 CUMULATIVE-GPA-IN    PIC 99v99 VALUE ZERO.
    05 CUMULATIVE-QP-IN     PIC 99v99 VALUE ZERO.
    05 CUMULATIVE-HOURS-IN  PIC 99v99 VALUE ZERO.

这可能不是您想要的。

查看文档并了解在 SELECT 上使用 FILE STATUS 的好处。每个 IO 都应该检查它的(每个文件分开的)FILE STATUS 字段。然后,您可以使用 FILE STATUS 字段(通过值为“10”的 88 级)检查文件结尾,减少 READ ... AT END ... NOT AT END .. 的曲折使用。 ..

88 分对你的成绩也有好处,而不是文字。请注意,如果添加“4”,最好添加一个 VALUE 为 4 且名称明确的字段,以便 reader 知道要添加的内容(4 的含义)。

除非您有复杂的计算,否则您可能更喜欢 ADD 1 TO field-name 而不是 COMPUTE field-name = field-name + 1

如果您有成绩测试,您会发现 EVALUATE 比嵌套或顺序 IF 更易于使用。

您还没有任何输出,无论是文件还是屏幕。看看这里和其他地方的例子,看看情况如何。如果您遇到困难,最好问一个新问题,否则答案会变得太复杂。一次一件事。