Menu

How to define input/output layout properly in this case

Emmad
2021-06-30
2021-07-02
  • Emmad

    Emmad - 2021-06-30

    I have the following code. I read a file (the data is shown at the top of the code). The fields: sales and profit are not correctly parsed and the last field in the output is truncated.

    The profit field could be positive or negative.

    I get the following output:

    0002>00.20/0000000.00/ 0000000.00<.55|Standard C
    0003>00.20/0000000.00/ 0000000.00<.27|Standard C
    0002>00.70/0000000.00/ 0000000.00<.63|Second Cla
    

    I suspect my layout description to be in error.

    Thank you for your help.

       *>INPUT FILE:
       *>     0002|00.20| $00016.45| $00005.55|Standard Class|
       *>     0003|00.20| $00011.78| $00004.27|Standard Class|
       *>     0002|00.70| $00018.59|-$00013.63|Second Class--|
       IDENTIFICATION DIVISION.
       PROGRAM-ID.    BASE1.
       ENVIRONMENT    DIVISION.
       CONFIGURATION  SECTION.
       SPECIAL-NAMES.
       REPOSITORY.    
              FUNCTION ALL INTRINSIC
              .
       INPUT-OUTPUT   SECTION.
       FILE-CONTROL.
    
           SELECT    FD-DATA-FILE ASSIGN TO  "SMALL.TXT" 
                     FILE STATUS              WS-IN-FILE-STATUS
                     ORGANIZATION IS LINE SEQUENTIAL
                     .                        
           SELECT   FD-OUT-FILE ASSIGN TO
                                             "OUT.TXT"
                     FILE STATUS             WS-OUT-FILE-STATUS
                     ORGANIZATION IS LINE SEQUENTIAL
                     .                   
      *> --------------------------------------------------------------
       DATA           DIVISION.       
       FILE           SECTION.
       FD  FD-DATA-FILE.
       01  FD-IN-REC        PIC X(50).
      *>---------------------------------------------------------------        
       FD  FD-OUT-FILE.
       01  FD-OUT-REC       PIC X(300).
      *>===============================================================
       WORKING-STORAGE SECTION.
      *>===============================================================
       01 WS-IN-FILE-STATUS                         PIC XX.
       01 WS-OUT-FILE-STATUS                        PIC XX.
       01 WS-LINES-READ-CNTR                        PIC 9(8).
       01 WS-MSG                                    PIC X(131).
      *>----------------------------------------------------------------
       01 WS-IN-REC.
    
           02   SOLD-QTY          PIC 9(4).
           02                                   F PIC X.
           02   SALE-DISCOUNT     PIC 9(2)V99.
           02                                   F PIC X.
           02   SALE-AMOUNT       PIC 9(6)V99.
           02                                   F PIC X.
           02   SALE-PROFIT       PIC S9(7)V99.
           02                                   F PIC X.
           02   SHIP-MODE         PIC X(14).
           02   F                                 PIC X.
       *>--------------------------------------------------------------   
        01 WS-OUT-REC.
    
           02   SOLD-QTY          PIC 9(4).
           02                                   F2 PIC X.
           02   SALE-DISCOUNT     PIC 9(2).99.
           02                                   F3 PIC X.
           02   SALE-AMOUNT       PIC 9(7).99.
           02                                   F4 PIC X.   
           02   SALE-PROFIT       PIC -9(7).99.
           02                                   F5 PIC X.
           02   SHIP-MODE         PIC X(14).
      *>----------------------
       PROCEDURE DIVISION.
    
           MOVE ZERO TO WS-LINES-READ-CNTR.
           OPEN OUTPUT FD-OUT-FILE.   
           OPEN INPUT FD-DATA-FILE.
    
           READ FD-DATA-FILE INTO WS-IN-REC.
    
           PERFORM  UNTIL WS-IN-FILE-STATUS NOT ZERO        
    
                   ADD 1 TO WS-LINES-READ-CNTR                
    
                   PERFORM MOVER
    
                   MOVE SPACES TO FD-OUT-REC
                   WRITE FD-OUT-REC  FROM WS-OUT-REC
                   READ FD-DATA-FILE INTO WS-IN-REC
    
          END-PERFORM
          .
       BYBY.
            DISPLAY "****".
            DISPLAY "IN FILE STATUS:" WS-IN-FILE-STATUS
            DISPLAY "FINISHED - PROCESSED:" 
                     WS-LINES-READ-CNTR
            CLOSE FD-DATA-FILE
            CLOSE FD-OUT-FILE
    
            STOP RUN.
    
       MOVER.
           INITIALIZE WS-OUT-REC.
           MOVE ">" TO F2. 
           Move "/" TO F3, F4. 
           Move "<" TO F5.
    
           MOVE   SOLD-QTY     OF WS-IN-REC TO SOLD-QTY      OF WS-OUT-REC
           MOVE   SHIP-MODE    OF WS-IN-REC TO SHIP-MODE  OF WS-OUT-REC
    
           MOVE FUNCTION NUMVAL(
                 FUNCTION SUBSTITUTE(SALE-DISCOUNT OF WS-IN-REC, '$', ' ')
                 )  TO SALE-DISCOUNT OF WS-OUT-REC.     
    
           MOVE FUNCTION NUMVAL(
                 FUNCTION SUBSTITUTE(SALE-AMOUNT OF WS-IN-REC, '$', ' ')
                 ) TO SALE-AMOUNT OF WS-OUT-REC.
    
           MOVE FUNCTION NUMVAL(
                 FUNCTION SUBSTITUTE(SALE-PROFIT OF WS-IN-REC, '$', ' ')
                 ) TO 
                 SALE-PROFIT OF WS-OUT-REC.
    
           .                 
      *>=====================================================================
    
     

    Last edit: Emmad 2021-06-30
    • Simon Sobisch

      Simon Sobisch - 2021-06-30

      Just some questions:

      • Is there a reason that you define the record as one big chunk and then have the "real" definitions in WORKING-STORAGE? Why not moving them up? Note: you can also specify multiple 01-level for a single FD.
      • Is there a reason for your REPOSITORY specification? The additional functions are at least not used in this part and the reason for ALL INTRINSIC is that you don't need to specify the FUNCTION keyword in the text (which allows you to do MOVE NUMVAL(SUBSTITUTE(VAR, '$', ' ')) TO VAR2, using that is primarily a style issue but it the style should be consistent)

      ... and the solution to your question: the defined input record already has "numeric fields as stored in COBOL with an implied decimal point and without any editing", you seem to want a plain PIC X with the appropriate size there.

      Note: your sample shows a missing check in GnuCOBOL, quoting COBOL202x:

      Argument-1 shall be an identifier that references a data item or identifier that is class alphabetic, alphanumeric, or national, or an alphanumeric or national literal.

      You use a numeric identifier here, GnuCOBOL should error (which would also would have helped you to spot the issue, I guess).

       
      • Emmad

        Emmad - 2021-06-30

        Thank you for your quick feedback. You are correct, of course, in all your comments.
        - I use READ INTO, but reading in FD area is good enough.
        - The REPOSITORY coding is there because I removed chuncks of the code that used it and left it as I was in a hurry to make a simple code sample,
        - Defining the data in X format is what I will test now hoping to get rid of the issue.
        Thanks again.

         
        • Emmad

          Emmad - 2021-06-30

          I have changed the layout definition of the input record to use Xs, Outut definition is the same and input data is the same.

             01 WS-IN-REC.
                 02   SOLD-QTY          PIC 9(4).
                 02                                   F PIC X.
                 02   SALE-DISCOUNT     PIC X(5).
                 02                                   F PIC XX.
                 02   SALE-AMOUNT       PIC X(9).
                 02                                   F PIC X.
                 02   SALE-PROFIT       PIC x(10).
                 02                                   F PIC X.
                 02   SHIP-MODE         PIC X(14).
                 02   F                                 PIC X.
          

          The result is still not good:

          0002>00.20/0000016.00/ 0000000.00<5|Standard Cla
          0003>00.20/0000011.00/ 0000000.00<7|Standard Cla
          0002>00.70/0000018.00/ 0000000.00<3|Second Class

          The decimal part is gone from SALE-AMOUNT and the SALE-PROFIT is not correct at all....

           
  • Simon Sobisch

    Simon Sobisch - 2021-06-30

    FUNCTION NUMVAL creates a numeric item, so of course you want a numeric item in your output (either a plain one if you want to work with the data later or an edited version if you want "nice looking" ones, like PIC $ZZ9.99-).
    If I did not count wrong then both AMOUNT and PROFIT are 10 bytes long - if in doubt I suggest to simply DISPLAY all input fields after the READ. If your input is wrong then there won't be a good NUMVAL result.

     
    • Emmad

      Emmad - 2021-06-30

      Thank you for your suggestion. I did it. Now it is working. I am not quite sure what happened but it worked.....!!! Of course, defining input fields as X instead of 9 as you suggested was key.
      Thank you for your patience.

      Here is the working code...

      ::cobolfree
         IDENTIFICATION DIVISION.
         PROGRAM-ID.    BASE1.
         ENVIRONMENT    DIVISION.
         CONFIGURATION  SECTION.
        *> SOURCE         COMPUTER.
        *> OBJECT         COMPUTER.
         SPECIAL-NAMES.
         REPOSITORY.    
                FUNCTION ALL INTRINSIC
                FUNCTION FUNC-COMPRESS
                FUNCTION FUNC-GetDayOfWeek
                .
         INPUT-OUTPUT   SECTION.
         FILE-CONTROL.
      
             SELECT    FD-DATA-FILE ASSIGN TO  "SMALL.TXT" 
                       FILE STATUS              WS-IN-FILE-STATUS
                       ORGANIZATION IS LINE SEQUENTIAL
                       .                        
             SELECT   FD-OUT-FILE ASSIGN TO
                                               "OUT.TXT"
                       FILE STATUS             WS-OUT-FILE-STATUS
                       ORGANIZATION IS LINE SEQUENTIAL
                       .                   
        *> --------------------------------------------------------------
         DATA           DIVISION.       
         FILE           SECTION.
         FD  FD-DATA-FILE.
         01  FD-IN-REC        PIC X(50).
        *>---------------------------------------------------------------        
         FD  FD-OUT-FILE.
      
         01  FD-OUT-REC       PIC X(300).
        *>===============================================================
         WORKING-STORAGE SECTION.
        *>===============================================================
         01 WS-IN-FILE-STATUS                         PIC XX.
         01 WS-OUT-FILE-STATUS                        PIC XX.
         01 WS-LINES-READ-CNTR                        PIC 9(8).
         01 WS-MSG                                    PIC X(131).
        *>---------------------------------------------------------------
        *>    I N P U T  /  O U T P U T  R E C O R D S        <WS-I/O>
        *>----------------------------------------------------------------
         01 WS-IN-REC.
      
             02   SOLD-QTY          PIC 9(4).
             02                                   F PIC X.
             02   SALE-DISCOUNT     PIC X(5).
             02                                   F PIC XX.
             02   SALE-AMOUNT       PIC X(9).
             02                                   F PIC X.
             02   SALE-PROFIT       PIC x(10).
             02                                   F PIC X.
             02   SHIP-MODE         PIC X(14).
             02   F                                 PIC X.
         *>--------------------------------------------------------------   
          01 WS-OUT-REC.
      
             02   SOLD-QTY          PIC 9(4).
             02                                   F2 PIC X.
             02   SALE-DISCOUNT     PIC 9(2).99.
             02                                   F3 PIC X.
             02   SALE-AMOUNT       PIC 9(7).99.
             02                                   F4 PIC X.   
             02   SALE-PROFIT       PIC -9(7).99.
             02                                   F5 PIC X.
             02   SHIP-MODE         PIC X(14).
        *>----------------------
         PROCEDURE DIVISION.
      
             MOVE ZERO TO WS-LINES-READ-CNTR.
             OPEN OUTPUT FD-OUT-FILE.   
             OPEN INPUT FD-DATA-FILE.
      
             READ FD-DATA-FILE INTO WS-IN-REC.
      
             PERFORM  UNTIL WS-IN-FILE-STATUS NOT ZERO        
      
                     ADD 1 TO WS-LINES-READ-CNTR                
                     PERFORM SHOW.
                     PERFORM MOVER
      
                     MOVE SPACES TO FD-OUT-REC
                     WRITE FD-OUT-REC  FROM WS-OUT-REC
                     READ FD-DATA-FILE INTO WS-IN-REC
      
            END-PERFORM
            .
         BYBY.
              DISPLAY "****".
              DISPLAY "IN FILE STATUS:" WS-IN-FILE-STATUS
              DISPLAY "FINISHED - PROCESSED:" 
                       WS-LINES-READ-CNTR
              CLOSE FD-DATA-FILE
              CLOSE FD-OUT-FILE
      
              STOP RUN.
      
         MOVER.
             INITIALIZE WS-OUT-REC.
             MOVE ">" TO F2. 
             Move "/" TO F3, F4. 
             Move "<" TO F5.
      
             MOVE   SOLD-QTY     OF WS-IN-REC TO SOLD-QTY   OF WS-OUT-REC
             MOVE   SHIP-MODE    OF WS-IN-REC TO SHIP-MODE  OF WS-OUT-REC
      
             MOVE FUNCTION NUMVAL(
                   FUNCTION SUBSTITUTE(SALE-DISCOUNT OF WS-IN-REC, '$', ' ')
                   )  TO SALE-DISCOUNT OF WS-OUT-REC.     
      
             MOVE FUNCTION NUMVAL(
                   FUNCTION SUBSTITUTE(SALE-AMOUNT OF WS-IN-REC, '$', ' ')
                   ) TO SALE-AMOUNT OF WS-OUT-REC.
      
             MOVE FUNCTION NUMVAL(
                   FUNCTION SUBSTITUTE(SALE-PROFIT OF WS-IN-REC, '$', ' ')
                   ) TO 
                   SALE-PROFIT OF WS-OUT-REC
             .                 
         SHOW.
             DISPLAY "---------------------------------"
             DISPLAY WS-LINES-READ-CNTR
             DISPLAY   "SOLD-QTY       =  " SOLD-QTY       OF WS-IN-REC               
             DISPLAY   "SALES-DISCOUNT =  " SALE-DISCOUNT  OF WS-IN-REC    
             DISPLAY   "SALES AMOUNT   =  " SALE-AMOUNT    OF WS-IN-REC  
             DISPLAY   "SALE PROFIT    =  " SALE-PROFIT    OF WS-IN-REC       
             DISPLAY   "SHIP MODE      =  " SHIP-MODE      OF WS-IN-REC       
             .
        *>=====================================================================
      
       

      Last edit: Simon Sobisch 2021-07-01
      • Simon Sobisch

        Simon Sobisch - 2021-07-01

        Just one further suggestion: it would be good common practice to check the io-status after both OPEN and possibly after the WRITE (while that one is unlikely to be an issue).

         
        • Emmad

          Emmad - 2021-07-01

          100% agree - I wanted to show only the problem. Thanks.

           
  • Vincent (Bryan) Coen

    File status should be checked after ALL file operations including Open (and only maybe close).

     
    • Emmad

      Emmad - 2021-07-01

      I usually check after open, read (or AT END), and write - But I never considered the check after Close. Nice to point to consider. Thanks.

       
      • Simon Sobisch

        Simon Sobisch - 2021-07-01

        For CLOSE there are only two non-zero status values listed in the standard:

        42 - the file was not open
        07 - The input-output statement is successfully executed but a CLOSE statement with the NO REWIND, REEL/UNIT, or FOR REMOVAL phrase or for an OPEN statement with the NO REWIND phrase references a physical file on a non-reel/unit medium.

         
  • Vincent (Bryan) Coen

    Should point out I rarely chech for status on close However I do create a WS switch for each file that I set zero for closed and 1 for open.

    Mostly because when using open I-O when the file does not exist it does not always create the file but I think that for v3.1.2 it does - forgotten so must remember to double check this one.

    Vince

     
  • Vincent (Bryan) Coen

    Also 42 is the one I might expect if I had done some sloppy coding :)

     
    • Emmad

      Emmad - 2021-07-02

      These are nice ideas. Thank you for telling me about them.

       

Anonymous
Anonymous

Add attachments
Cancel