COBOL:当两者都有返回码10时,如何区分文件结尾和垃圾值?

时间:2018-09-27 08:16:06

标签: cobol

我正在使用Fujitsu COBOL,并且有一种情况,我必须读取文件,如果有垃圾值,那么我想放弃工作。

当有垃圾值时,返回码为10,但是要抓住的是,即使有EOF(文件末尾),返回码也为10。

请帮助我如何根据返回码区分这两个事件?

2 个答案:

答案 0 :(得分:5)

在非常早期的PC(MS-DOS 1.0)上,Ctrl + Z(X“ 1A”)被用作文本文件的文件结尾。您的编译器可能会检测到该字符并将其视为if文件的末尾,而不是允许处理文件的其余部分。

在OEM / DOS字符集中,X“ 1A”显示为向右箭头。 (您在评论中提到了一个箭头。)我创建了一个简短的文件,其中包含四个要测试的记录。

原始文件:

Record1
Record2
Record3
Record4

我用X“ 1A”代替了“ 3”。在十六进制编辑器中,它显示为

Hex Edit image of modified record

请注意,x“ 1A”字符显示为向右箭头。

A编写了一个程序(未显示)来读取显示修改后的文件输出的文件。

Record1
Record2
Record
0003 lines read

文件结尾出现在X“ 1A”。

以下程序可用于检查X“ 1A”和“识别损坏的记录的出现...,以便[您]可以更正文件”。

   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

答案 1 :(得分:0)

在下面的代码中,我刚刚展示了一种当文件状态代码为10时区分文件结尾和垃圾值的方法。

在程序中,正在读取文件。正在读取的输入文件的FILE STATUSWS-ST。记录布局仅是一个名为NAME1的字段。我不太确定(在您的情况下)垃圾值如何导致FILE STATUS的值为10。但是,为了重现您所面临的错误,每当WS-ST字段具有NAME1作为值时,我都将10移至SRINIVASAN。当READ获得NAME1时,我也打破了SRINIVASAN循环。

READ循环之后,正在检查FILE STATUS数据项。如果它保持10,则发出另一个READ。在这里,我碰到了FILE STATUS46。

  

46-已尝试对以INPUT或I-O模式打开的文件执行顺序读取操作,但未建立有效的下一条记录。

处理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 ****************************

输出:程序正常结束。 RC00。

********************************* TOP OF DATA **********************************
RECORD01: BHUTAN                                                                
RECORD02: NEPAL                                                                 
END OF FILE                                                                     
******************************** BOTTOM OF DATA ********************************

示例3:

输入:错误记录SRINIVASANBHUTANNEPAL之间。可能在这两个国家之间的边界:)?

***************************** Top of Data ******************************
BHUTAN                                                                  
SRINIVASAN                                                              
NEPAL                                                                   
**************************** Bottom of Data ****************************

输出:程序以RC 16结尾。程序未读取第三条记录,因为第二条记录出错。

********************************* TOP OF DATA **********************************
RECORD01: BHUTAN                                                                
RECORD02: SRINIVASAN                                                            
RECORD02 IS ERRORED!                                                            
******************************** BOTTOM OF DATA ********************************

示例4:

输入:输入文件为空

输出:程序正常结束。

********************************* TOP OF DATA **********************************
END OF FILE                                                                     
******************************** BOTTOM OF DATA ********************************

希望这会有所帮助!