File I/O with COBOL

Welcome back to my blog! In the previous post, we covered how to set up the environment for COBOL. Now that we have everything up and running, it’s time to dive deeper into the world of programming and learn about an essential concept – file I/O. In this post, we will be focusing on how to read and write files. So, let’s get started!

Full disclosure: I’m not a COBOL developer, I’m just learning it.

To read a file in COBOL we need to declare the file to work with in the environment division.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT-FILE ASSIGN TO "input.txt".

With the above we declare a logical name that we can use in our COBOL application which is associated with the physical file “input.txt”.

Next step is to define the file stucture in the data division:

DATA DIVISION.
FILE SECTION.
FD INPUT-FILE.
01 INPUT-RECORD PIC X(80).

COBOL is designed to work with fixed-length records, and the language provides features that make it easy to define and manipulate these records. The above simply says that the file is made of lines of 80 characters.

In the working storage section, we need to declare a helper variable to keep track of the end of file state.

WORKING-STORAGE SECTION.
01 WS-END-OF-FILE PIC 9(1) VALUE 0.

The action plays in the procedure division, where we:

  • open the file
  • read line by line until we reach the end of file

       PROCEDURE DIVISION.
       MAIN-LOGIC.
           OPEN INPUT INPUT-FILE
           READ INPUT-FILE INTO INPUT-RECORD
           PERFORM UNTIL WS-END-OF-FILE = 1
               DISPLAY INPUT-RECORD
               READ INPUT-FILE INTO INPUT-RECORD
               AT END SET WS-END-OF-FILE TO 1
           END-PERFORM
           CLOSE INPUT-FILE
           STOP RUN.    

The code for reading a file and displaying its contents is surprisingly straightforward. First, the program reads the first record of the file. Then, it enters a loop where it continues to read and display each subsequent record until it reaches the end of the file. To do this, it uses a simple flag variable called WS-END-OF-FILE, which is set to 1 when the end of the file is reached, causing the loop to stop. And that’s it! With just a few lines of code, you can quickly and easily read and display the contents of any file using COBOL.

Here is the full code, in case you want to play around with it (just compile with cobc -x YOURFILENAME.COB)

       IDENTIFICATION DIVISION.
       PROGRAM-ID. READ-FILE.
       
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       SELECT INPUT-FILE ASSIGN TO "input.txt".
       
       DATA DIVISION.
       FILE SECTION.
       FD INPUT-FILE.
       01 INPUT-RECORD PIC X(80).
       
       WORKING-STORAGE SECTION.
       01 WS-END-OF-FILE PIC 9(1) VALUE 0.
       
       PROCEDURE DIVISION.
       MAIN-LOGIC.
           OPEN INPUT INPUT-FILE
           READ INPUT-FILE INTO INPUT-RECORD
           PERFORM UNTIL WS-END-OF-FILE = 1
               DISPLAY INPUT-RECORD
               READ INPUT-FILE INTO INPUT-RECORD
               AT END SET WS-END-OF-FILE TO 1
           END-PERFORM
           CLOSE INPUT-FILE
           STOP RUN.    

But how do we write files? This is actually more or less the same pattern, just that we need to declare an output file as well. Let’s see how we would copy from one file to another instead of writing the lines to the standard output:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. READ-FILE.
       
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       SELECT INPUT-FILE ASSIGN TO "input.txt".
       SELECT OUTPUT-FILE ASSIGN TO "output.txt".
       
       DATA DIVISION.
       FILE SECTION.
       FD INPUT-FILE.
       01 INPUT-RECORD PIC X(80).
       FD OUTPUT-FILE.
       01 OUTPUT-RECORD PIC X(80).
       
       WORKING-STORAGE SECTION.
       01 WS-END-OF-FILE PIC 9(1) VALUE 0.
       
       PROCEDURE DIVISION.
       MAIN-LOGIC.
           OPEN INPUT INPUT-FILE
           OPEN OUTPUT OUTPUT-FILE
           READ INPUT-FILE INTO INPUT-RECORD
           PERFORM UNTIL WS-END-OF-FILE = 1          
               WRITE OUTPUT-RECORD FROM INPUT-RECORD
               READ INPUT-FILE INTO INPUT-RECORD
               AT END SET WS-END-OF-FILE TO 1
           END-PERFORM
           CLOSE INPUT-FILE
           CLOSE OUTPUT-FILE
           STOP RUN.    

This works, but the last record looks a bit odd. Maybe something we can fix in the next blog post! Not sure what comes next, but I would like to experiment with user input and/or reading program arguments.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.