COBOL85-Обработка файлов
Я читаю входной файл и записываю его в выходной файл до достижения EOF, но проблема с моей программой заключается в том, что после записи записей в выходной файл до достижения EOF выходной файл содержит одну дополнительную запись по сравнению с входным файлом, т.е. если входные файлы содержат 10 записей, то выходной файл содержит 11 записей. И дополнительная запись в выходном файле совпадает с последней записью, т.е. последняя запись повторяется дважды.
Поэтому, пожалуйста, дайте мне знать, в чем проблема с моим кодом.
Код моей программы.
?SYMBOLS
?INSPECT
IDENTIFICATION DIVISION.
PROGRAM-ID. InsertRecords.
AUTHOR. XYZ.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT StudentRecords
ASSIGN TO "=MKFIL1"
ORGANIZATION IS SEQUENTIAL
ACCESS IS SEQUENTIAL
FILE STATUS IS WS-FILE-STATUS.
SELECT NEWStudentRecords
ASSIGN TO "=MKFIL2"
ORGANIZATION IS SEQUENTIAL
ACCESS IS SEQUENTIAL
FILE STATUS IS WS-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD StudentRecords.
01 StudentRecord.
05 Student PIC X(431).
FD NewStudentRecords.
01 NewStudentRecord PIC X(431).
WORKING-STORAGE SECTION.
01 WS-DETAIL-RECORD PIC X(431).
01 EOF PIC X(3) VALUE "NO".
01 WS-FILE-STATUS PIC XX VALUE ZEROES.
01 WS-SOURCE.
05 PIC X(16) VALUE X"000102030405060708090A0B0C0D0E0F".
05 PIC X(16) VALUE X"101112131415161718191A1B1C1D1E1F".
05 PIC X(16) VALUE X"202122232425262728292A2B2C2D2E2F".
05 PIC X(16) VALUE X"303132333435363738393A3B3C3D3E3F".
05 PIC X(16) VALUE X"404142434445464748494A4B4C4D4E4F".
05 PIC X(16) VALUE X"505152535455565758595A5B5C5D5E5F".
05 PIC X(16) VALUE X"606162636465666768696A6B6C6D6E6F".
05 PIC X(16) VALUE X"707172737475767778797A7B7C7D7E7F".
05 PIC X(16) VALUE X"808182838485868788898A8B8C8D8E8F".
05 PIC X(16) VALUE X"909192939495969798999A9B9C9D9E9F".
05 PIC X(16) VALUE X"A0A1A2A3A4A5A6A7A8A9AAABACADAEAF".
05 PIC X(16) VALUE X"B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF".
05 PIC X(16) VALUE X"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF".
05 PIC X(16) VALUE X"D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF".
05 PIC X(16) VALUE X"E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF".
05 PIC X(16) VALUE X"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF".
01 WS-TARGET.
05 PIC X(16) VALUE X"20202020202020202020202020202020".
05 PIC X(16) VALUE X"20202020202020202020202020202020".
05 PIC X(16) VALUE X"202122232425262728292A2B2C2D2E2F".
05 PIC X(16) VALUE X"303132333435363738393A3B3C3D3E3F".
05 PIC X(16) VALUE X"404142434445464748494A4B4C4D4E4F".
05 PIC X(16) VALUE X"505152535455565758595A5B5C5D5E5F".
05 PIC X(16) VALUE X"606162636465666768696A6B6C6D6E6F".
05 PIC X(16) VALUE X"707172737475767778797A7B7C7D7E20".
05 PIC X(16) VALUE X"20202020202020202020202020202020".
05 PIC X(16) VALUE X"20202020202020202020202020202020".
05 PIC X(16) VALUE X"20202020202020202020202020202020".
05 PIC X(16) VALUE X"20202020202020202020202020202020".
05 PIC X(16) VALUE X"20202020202020202020202020202020".
05 PIC X(16) VALUE X"20202020202020202020202020202020".
05 PIC X(16) VALUE X"20202020202020202020202020202020".
05 PIC X(16) VALUE X"20202020202020202020202020202020".
PROCEDURE DIVISION.
BEGIN.
OPEN INPUT StudentRecords
OPEN OUTPUT NewStudentRecords
PERFORM UNTIL EOF = "YES"
READ StudentRecords
AT END MOVE "YES" TO EOF
END-READ
MOVE Student TO WS-DETAIL-RECORD
INSPECT WS-DETAIL-RECORD CONVERTING WS-SOURCE TO WS-TARGET
WRITE NewStudentRecord FROM WS-DETAIL-RECORD
END-PERFORM
CLOSE StudentRecords
CLOSE NewStudentRecords
STOP RUN.
2 ответа
COCOL
не знает, что вы достигли EOF, пока не попытаетесь прочитать последнюю запись.
Следовательно, когда вы читаете последнюю запись, EOF
является ((не ** установлен на YES
, таким образом, следующий reocrd - "чтение". Это читать не удается и EOF
установлен в YES
- но вы уже запустили цикл, поэтому данные в буфере записываются снова.
Следовательно, вам нужно будет сосредоточить свою обработку на EOF
статус. Лично я бы переместил обработку в другой абзац и использовал бы
PERFORM UNTIL EOF = "YES"
READ StudentRecords
AT END MOVE "YES" TO EOF
END-READ
IF EOF = "NO" PERFORM NEW-PARAGRAPH
END-PERFORM
@Magoo - это правильно.
Вы уже закодировали FILE STATUS
на ваше SELECT
s, вы можете сделать вещи намного понятнее, используя его.
Чтобы избежать путаницы, вы должны кодировать два отдельных FILE STATUS
поля.
На FILE STATUS
поле для входного файла, код 88 (condition name)
для VALUE
из "10"
,
OPEN input file, check file status is zero (another 88)
OPEN output file, check file status is zero (another 88)
Initial Processing
READ input file, check file status: if 10 (88) you have an empty file,
do something reasonable, else if non-zero, report it.
Loop until FILE STATUS field for input file is "10" (88)
process input record
Read input file
End-Loop
Final Processing check file status is zero (88)
CLOSE input file, check file status is zero (88)
All Done
Эта техника, где первый READ
известен как "чтение заправки", предотвращает путаницу использования AT END/NOT AT END
или сразу же проверить, что AT END
только что установил.