问题
I am working on Fujitsu COBOL and there is a situation where I have to read the file and if there is a junk value then I want to abend the job.
When there is a junk value the return code is 10 but the catch is that when there is EOF (end of file) even then the return code is 10.
Please help me out on how can I differentiate between these two events based on the return code?
回答1:
On very early PCs (MS-DOS 1.0), a Ctrl+Z (X"1A") was used as end-of-file for text files. Your compiler is likely detecting that character and treating it as end-if-file instead of allowing the remainder of the file to be processed.
In the OEM/DOS character set, X"1A" appears as a right-pointing arrow. (You mentioned an arrow in a comment.) I created a short file with four records for testing.
The original file:
Record1
Record2
Record3
Record4
I replaced the "3" with X"1A". In a hex editor, it appears as,
Notice that the x"1A" character appears as a right-pointing arrow.
A wrote a program (not shown) to read the file displaying the output of the modified file.
Record1
Record2
Record
0003 lines read
End of file occurred at the X"1A".
The following program may be used to check for X"1A" and "identify the corrupt record occurrence ... so that [you] can correct the file".
program-id. ctrl-z.
environment division.
input-output section.
file-control.
select in-file assign "ctrl-z.txt"
organization sequential
.
data division.
file section.
fd in-file.
1 in-char pic x.
working-storage section.
1 line-count binary pic 9(4) value 0.
1 msg-txt pic x(25) value "lines read".
88 error-msg value "lines read before cntrl-z".
1 eof-in-file-flag pic 9 value 0.
88 eof-in-file value 1.
procedure division.
begin.
open input in-file
read in-file
at end set eof-in-file to true
end-read
perform until eof-in-file
evaluate in-char
when x"0A"
add 1 to line-count
when x"1A"
set error-msg to true
set eof-in-file to true
exit perform
when other
continue
end-evaluate
read in-file
at end set eof-in-file to true
end-read
end-perform
close in-file
display line-count space msg-txt
stop run
.
end program ctrl-z.
The result was:
0002 lines read before cntrl-z
回答2:
In the following code, I've just shown a method of differentiating end of file and junk value when both have File Status code of 10.
In the program, a file is being read. FILE STATUS
for the input file being read is WS-ST
. Record layout is just 1 field named as NAME1
. I'm not really sure how a junk value (in your case) is causing the FILE STATUS
to have 10 as value. But, in a way to reproduce the error you're facing, I've moved 10 to WS-ST
, whenever NAME1
field have SRINIVASAN
as value. I've also broken the READ
loop, when NAME1
has got SRINIVASAN
.
After the READ
loop, the FILE STATUS
data item is being checked. If it holds 10, another READ
is issued. Here, I just came across FILE STATUS
46.
46 - A sequential READ operation has been tried on a file open in the INPUT or I-O mode but no valid next record has been established.
Handling FILE STATUS
46 genuinely lets you know if the file has really reached its end. Going by this way, you can certainly differentiate EOF with junk value. Please go through the examples at the bottom of this answer and you may get some clarity.
ID DIVISION.
PROGRAM-ID. EOF1.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INDD ASSIGN TO INDD
FILE STATUS IS WS-ST.
DATA DIVISION.
FILE SECTION.
FD INDD.
01 NAME1 PIC X(10).
WORKING-STORAGE SECTION.
01 WS-ST PIC 9(2) VALUE 0.
01 WS-READ PIC 9(2) VALUE 0.
01 WS-SWITCHES.
05 INDD-END PIC X(1) VALUE 'N'.
88 INDD-EOF VALUE 'Y'.
PROCEDURE DIVISION.
OPEN INPUT INDD.
PERFORM 100-READ THRU 100-EXIT UNTIL INDD-EOF.
IF WS-ST EQUAL 10
READ INDD
DISPLAY 'READ FILE STATUS: ' WS-ST
IF WS-ST EQUAL 46
DISPLAY 'END OF FILE'
ELSE
DISPLAY 'RECORD' WS-READ ' IS ERRORED!'
MOVE 16 TO RETURN-CODE
CLOSE INDD
STOP RUN
END-IF
ELSE
ADD 1 TO WS-READ
END-IF.
CLOSE INDD.
STOP RUN.
100-READ.
READ INDD
AT END
SET INDD-EOF TO TRUE
GO TO 100-EXIT
END-READ.
ADD 1 TO WS-READ.
DISPLAY 'READ FILE STATUS: ' WS-ST.
DISPLAY 'RECORD' WS-READ ': ' NAME1.
IF NAME1 EQUAL 'SRINIVASAN'
MOVE 10 TO WS-ST
SET INDD-EOF TO TRUE
END-IF.
100-EXIT. EXIT.
Several samples of Input and output are shown below:
Example 1:
Input: 3rd record is errored.
***************************** Top of Data ******************************
BHUTAN
NEPAL
SRINIVASAN
**************************** Bottom of Data ****************************
Output: Program ended with RC 16. Program didn't read further.
********************************* TOP OF DATA **********************************
RECORD01: BHUTAN
RECORD02: NEPAL
RECORD03: SRINIVASAN
RECORD03 IS ERRORED!
******************************** BOTTOM OF DATA ********************************
Example 2:
Input: No error record this time.
***************************** Top of Data ******************************
BHUTAN
NEPAL
**************************** Bottom of Data ****************************
Output: Program ended normally. RC 00.
********************************* TOP OF DATA **********************************
RECORD01: BHUTAN
RECORD02: NEPAL
END OF FILE
******************************** BOTTOM OF DATA ********************************
Example 3:
Input: Error record SRINIVASAN
is in between BHUTAN
and NEPAL
. Might be in the border between these 2 countries :) ?
***************************** Top of Data ******************************
BHUTAN
SRINIVASAN
NEPAL
**************************** Bottom of Data ****************************
Output: Program ends with RC 16. Program didn't read 3rd record as the 2nd one is errored.
********************************* TOP OF DATA **********************************
RECORD01: BHUTAN
RECORD02: SRINIVASAN
RECORD02 IS ERRORED!
******************************** BOTTOM OF DATA ********************************
Example 4:
Input: Empty Input file
Output: Program ends normally.
********************************* TOP OF DATA **********************************
END OF FILE
******************************** BOTTOM OF DATA ********************************
Hope this helps!
来源:https://stackoverflow.com/questions/52532436/cobol-how-to-differentiate-between-end-of-file-and-junk-value-when-both-have-re