Дополнительный фон: это продолжение Добавление двух целых чисел, дающих нежелательный результат в коболе.
Поскольку входные данные состоят из строк, а для вычислений нужны целые числа, эта программа массово считывает каждую строку, затем считывает каждое поле отдельно из файла и преобразует нужные поля в числа при сохранении их в таблице раздела рабочей памяти.
Теперь по какой-то причине правильно читается и сохраняется только первая запись. Остальные записи читаются как пустые или нулевые, я думаю, хотя содержимое файла после первой записи явно не является нулевым.
Вот мой текущий код для полной программы:
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.
и вот входной файл, счет:
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 и далее), имеет отдельные части, отображаемые следующим образом:
MS 1 - Join Grps
MS 1 - Join Grps
Group Project
Group Project
5
00000000000005
5
00000000000005
Это то, что я ожидаю. Каждый элемент повторяется, первая итерация — это структура входного файла, а вторая — структура рабочего раздела хранилища. Разница в том, что входные структуры читаются как все строки длиной 20 и 14, а структуры хранения форматируются как две строки длиной 20 и два целых числа длиной 14. Числовые строки преобразуются в целые числа и сохраняются в рабочей памяти, как указано ранее. Вывод DISPLAYs второй строки выглядит следующим образом:
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 и/или разбить код наSECTION
s (или только абзацы в стиле pre-cobol85) для повышения удобочитаемости (но это больше вопрос стиля, так что просто Примечание). Если вы заработаете сами, пожалуйста, ответьте сами себе (вопросы и ответы), в противном случае, пожалуйста, оставьте заметку после редактирования. - person Simon Sobisch   schedule 22.09.2020