COBOL: How to differentiate between end of file and junk value when both have return code 10?

给你一囗甜甜゛ 提交于 2019-12-24 08:28:28

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!