Чтение таблицы из файла приводит к сохранению только первой записи

Дополнительный фон: это продолжение Добавление двух целых чисел, дающих нежелательный результат в коболе.

Поскольку входные данные состоят из строк, а для вычислений нужны целые числа, эта программа массово считывает каждую строку, затем считывает каждое поле отдельно из файла и преобразует нужные поля в числа при сохранении их в таблице раздела рабочей памяти.

Теперь по какой-то причине правильно читается и сохраняется только первая запись. Остальные записи читаются как пустые или нулевые, я думаю, хотя содержимое файла после первой записи явно не является нулевым.

Вот мой текущий код для полной программы:

    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 для заработанных баллов, а остальные просто вычисляются до нуля, потому что они считываются как пробелы.

Как я могу заставить свою программу правильно прочитать остальную часть файла?


person Jordan Renaud    schedule 22.09.2020    source источник
comment
Ради интереса: -debug не вызывает исключений? На первый взгляд кажется, что вы, вероятно, хотите удалить ODO (OCCURS DEPENDIG ON) из входного файла. И вы можете использовать EXIT PERFORM вместо установки и последующей проверки переменной eof и/или разбить код на SECTIONs (или только абзацы в стиле pre-cobol85) для повышения удобочитаемости (но это больше вопрос стиля, так что просто Примечание). Если вы заработаете сами, пожалуйста, ответьте сами себе (вопросы и ответы), в противном случае, пожалуйста, оставьте заметку после редактирования.   -  person Simon Sobisch    schedule 22.09.2020
comment
Примечание. Я отредактировал ваш вопрос, чтобы следовать правилам SO, пожалуйста, взгляните на редактирование. Мы можем общаться через комментарии, которые также очищаются автоматически, за исключением комментариев, за которые проголосовали [они предназначены для того, чтобы дать представление о вопросе / ответе], или также через доски обсуждений. еще одно примечание: хорошо, что вы разместили его как дополнительный вопрос, и ваши вопросы показывают исследования, поэтому они идеально подходят здесь.   -  person Simon Sobisch    schedule 22.09.2020
comment
Я ценю ваше понимание и правки, это то, что я мог бы сделать, но моя единственная реальная цель - иметь работающую программу, которая принимает определенные входные данные и возвращает определенный выходной отчет. По сути, на этом уроке по языкам программирования нам даны группы и задание под названием «Четыре программы». Во-первых, мы можем реализовать их на любом языке, который захотим. Потом пришлось делать это на Фортране 66 (IV), а теперь на Коболе. Таким образом, нужно не столько знать алгоритмы, необходимые для получения необходимого вывода, сколько выяснить, как реализовать одни и те же алгоритмы на разных языках, и наблюдать, как язык   -  person Jordan Renaud    schedule 23.09.2020
comment
(2) вы пишете программу, может упростить процесс.   -  person Jordan Renaud    schedule 23.09.2020
comment
Да, и чтобы ответить на ваш вопрос, добавление флага -debug в мой файл launch.json на самом деле не повлияло на вывод консоли. Я использую отладчик (на самом деле впервые), чтобы пройти через него, но он все еще не помогает выяснить, почему он не читает все, как я хочу.   -  person Jordan Renaud    schedule 23.09.2020


Ответы (1)


Оказывается, при чтении таблицы из файла нижний индекс для доступа к текущей строке всегда равен 1, поэтому вместо чтения RECORD-COUNT в качестве нижнего индекса элементов INPUT я просто ставлю 1 для всех из них, и программа работает как положено!

person Jordan Renaud    schedule 23.09.2020
comment
В файле есть только оптическая таблица. Имейте в виду, что READ прочитает одну строку и поместит ее в запись, которую вы ему скажете. Каждая из этих записей является одной записью оптической таблицы, поэтому вы, скорее всего, вообще отбросите OCCURS. Для хороших вопросов и ответов в SO я предлагаю отредактировать ваш ответ с обновленным кодом (частью) вместе с вашим объяснением и принять ваш ответ, поскольку он работает для меня. - person Simon Sobisch; 23.09.2020
comment
Да, мне пришлось ждать 21 час, чтобы принять свой собственный ответ, я все еще жду, но отредактирую позже, когда меня не будет на работе. - person Jordan Renaud; 24.09.2020
comment
ping для принятия ответа (в настоящее время вопрос отображается как отвеченный, но не решенный) - person Simon Sobisch; 29.09.2020