COBOL:当两者都有 return 代码 10 时,如何区分文件结尾和垃圾值?
COBOL: How to differentiate between end of file and junk value when both have return code 10?
我正在使用 Fujitsu COBOL,在这种情况下我必须读取文件,如果有垃圾值,那么我想中止工作。
当存在垃圾值时,return 代码为 10,但要注意的是,即使存在 EOF(文件结尾),return 代码也为 10。
请帮助我如何根据 return 代码区分这两个事件?
在下面的代码中,我刚刚展示了一种区分文件状态代码为 10 的文件结尾和垃圾值的方法。
在程序中,正在读取一个文件。 FILE STATUS
正在读取的输入文件是 WS-ST
。记录布局只是 1 个名为 NAME1
的字段。我不太确定垃圾值(在您的情况下)如何导致 FILE STATUS
具有 10 作为值。但是,为了重现您面临的错误,只要 NAME1
字段具有 SRINIVASAN
作为值,我就将 10 移至 WS-ST
。当 NAME1
得到 SRINIVASAN
时,我还打破了 READ
循环。
在READ
循环之后,正在检查FILE STATUS
数据项。如果它持有 10,则发出另一个 READ
。在这里,我刚刚遇到 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.
处理 FILE STATUS
46 真正让您知道文件是否真的已结束。通过这种方式,您当然可以将 EOF 与垃圾价值区分开来。请仔细阅读此答案底部的示例,您可能会有所了解。
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.
输入和输出的几个示例如下所示:
示例 1:
输入:第三条记录有误。
***************************** Top of Data ******************************
BHUTAN
NEPAL
SRINIVASAN
**************************** Bottom of Data ****************************
输出:程序以 RC 16 结束。程序没有进一步读取。
********************************* TOP OF DATA **********************************
RECORD01: BHUTAN
RECORD02: NEPAL
RECORD03: SRINIVASAN
RECORD03 IS ERRORED!
******************************** BOTTOM OF DATA ********************************
示例 2:
输入:这次没有错误记录。
***************************** Top of Data ******************************
BHUTAN
NEPAL
**************************** Bottom of Data ****************************
输出:程序正常结束。 RC 00。
********************************* TOP OF DATA **********************************
RECORD01: BHUTAN
RECORD02: NEPAL
END OF FILE
******************************** BOTTOM OF DATA ********************************
示例 3:
输入:错误记录 SRINIVASAN
在 BHUTAN
和 NEPAL
之间。可能在这两个国家的边界上:) ?
***************************** Top of Data ******************************
BHUTAN
SRINIVASAN
NEPAL
**************************** Bottom of Data ****************************
输出:程序以 RC 16 结束。程序没有读取第 3 条记录,因为第 2 条记录出错。
********************************* TOP OF DATA **********************************
RECORD01: BHUTAN
RECORD02: SRINIVASAN
RECORD02 IS ERRORED!
******************************** BOTTOM OF DATA ********************************
示例 4:
输入:空输入文件
输出:程序正常结束。
********************************* TOP OF DATA **********************************
END OF FILE
******************************** BOTTOM OF DATA ********************************
希望对您有所帮助!
在非常早期的 PC (MS-DOS 1.0) 上,Ctrl+Z (X"1A") 被用作文本文件的文件结尾。您的编译器可能会检测到该字符并将其视为 end-if-file 而不是允许处理文件的其余部分。
在OEM/DOS字符集中,X"1A"显示为右向箭头。 (你在评论中提到了一个箭头。)我创建了一个包含四个记录的短文件用于测试。
原文件:
Record1
Record2
Record3
Record4
我用 X"1A" 替换了 "3"。在十六进制编辑器中,它显示为,
请注意 x"1A" 字符显示为右向箭头。
A 编写了一个程序(未显示)来读取显示修改文件输出的文件。
Record1
Record2
Record
0003 lines read
文件结束出现在 X"1A"。
以下程序可用于检查 X"1A" 和 "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.
结果是:
0002 lines read before cntrl-z
我正在使用 Fujitsu COBOL,在这种情况下我必须读取文件,如果有垃圾值,那么我想中止工作。
当存在垃圾值时,return 代码为 10,但要注意的是,即使存在 EOF(文件结尾),return 代码也为 10。
请帮助我如何根据 return 代码区分这两个事件?
在下面的代码中,我刚刚展示了一种区分文件状态代码为 10 的文件结尾和垃圾值的方法。
在程序中,正在读取一个文件。 FILE STATUS
正在读取的输入文件是 WS-ST
。记录布局只是 1 个名为 NAME1
的字段。我不太确定垃圾值(在您的情况下)如何导致 FILE STATUS
具有 10 作为值。但是,为了重现您面临的错误,只要 NAME1
字段具有 SRINIVASAN
作为值,我就将 10 移至 WS-ST
。当 NAME1
得到 SRINIVASAN
时,我还打破了 READ
循环。
在READ
循环之后,正在检查FILE STATUS
数据项。如果它持有 10,则发出另一个 READ
。在这里,我刚刚遇到 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.
处理 FILE STATUS
46 真正让您知道文件是否真的已结束。通过这种方式,您当然可以将 EOF 与垃圾价值区分开来。请仔细阅读此答案底部的示例,您可能会有所了解。
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.
输入和输出的几个示例如下所示:
示例 1:
输入:第三条记录有误。
***************************** Top of Data ******************************
BHUTAN
NEPAL
SRINIVASAN
**************************** Bottom of Data ****************************
输出:程序以 RC 16 结束。程序没有进一步读取。
********************************* TOP OF DATA **********************************
RECORD01: BHUTAN
RECORD02: NEPAL
RECORD03: SRINIVASAN
RECORD03 IS ERRORED!
******************************** BOTTOM OF DATA ********************************
示例 2:
输入:这次没有错误记录。
***************************** Top of Data ******************************
BHUTAN
NEPAL
**************************** Bottom of Data ****************************
输出:程序正常结束。 RC 00。
********************************* TOP OF DATA **********************************
RECORD01: BHUTAN
RECORD02: NEPAL
END OF FILE
******************************** BOTTOM OF DATA ********************************
示例 3:
输入:错误记录 SRINIVASAN
在 BHUTAN
和 NEPAL
之间。可能在这两个国家的边界上:) ?
***************************** Top of Data ******************************
BHUTAN
SRINIVASAN
NEPAL
**************************** Bottom of Data ****************************
输出:程序以 RC 16 结束。程序没有读取第 3 条记录,因为第 2 条记录出错。
********************************* TOP OF DATA **********************************
RECORD01: BHUTAN
RECORD02: SRINIVASAN
RECORD02 IS ERRORED!
******************************** BOTTOM OF DATA ********************************
示例 4:
输入:空输入文件
输出:程序正常结束。
********************************* TOP OF DATA **********************************
END OF FILE
******************************** BOTTOM OF DATA ********************************
希望对您有所帮助!
在非常早期的 PC (MS-DOS 1.0) 上,Ctrl+Z (X"1A") 被用作文本文件的文件结尾。您的编译器可能会检测到该字符并将其视为 end-if-file 而不是允许处理文件的其余部分。
在OEM/DOS字符集中,X"1A"显示为右向箭头。 (你在评论中提到了一个箭头。)我创建了一个包含四个记录的短文件用于测试。
原文件:
Record1
Record2
Record3
Record4
我用 X"1A" 替换了 "3"。在十六进制编辑器中,它显示为,
请注意 x"1A" 字符显示为右向箭头。
A 编写了一个程序(未显示)来读取显示修改文件输出的文件。
Record1
Record2
Record
0003 lines read
文件结束出现在 X"1A"。
以下程序可用于检查 X"1A" 和 "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.
结果是:
0002 lines read before cntrl-z