cv.cm

Coding · Programming languages

COBOL tutorial for beginners

7 min read

Short answer

COBOL (Common Business-Oriented Language) is a compiled language designed for business data processing: records, files, reports and exact decimal arithmetic. Programs are split into four divisions, data is described with PIC (picture) clauses, and the code reads like English sentences such as ADD AMOUNT TO TOTAL. It still runs core systems in banks, insurers and governments, mostly on IBM mainframes. You can learn it for free with the GnuCOBOL compiler: cobc -x hello.cob.

What COBOL is and who uses it

COBOL was designed in 1959 by the CODASYL committee, with strong influence from Grace Hopper's earlier FLOW-MATIC language. It is standardized by ISO; later standards added structured programming, object orientation and other features, and the most recent revision was published in 2023.

COBOL is used for batch processing and transaction systems: account processing, payroll, insurance claims, tax and benefit systems. Much of this code runs on IBM Z mainframes with IBM Enterprise COBOL, together with CICS for transactions and Db2 for data. Jobs maintaining and modernizing these systems remain common.

Install GnuCOBOL and run Hello, world

GnuCOBOL is a free compiler that translates COBOL to C and then to a native program. It is available as the gnucobol package on many Linux distributions and in Homebrew on macOS; Windows users can use WSL or a prebuilt package.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. HELLO.
       PROCEDURE DIVISION.
           DISPLAY "Hello, world!".
           STOP RUN.
cobc -x hello.cob
./hello
# Hello, world!

The code uses the traditional fixed format: columns 1 to 6 are for sequence numbers, column 7 marks comments (*) or continuation lines, Area A (columns 8 to 11) holds division, section and paragraph names, and Area B (columns 12 to 72) holds statements. GnuCOBOL also accepts free-format source with cobc -x -free. The option -x builds an executable instead of a module.

The four divisions

DivisionPurpose
IDENTIFICATION DIVISIONNames the program (PROGRAM-ID)
ENVIRONMENT DIVISIONConnects the program to the outside world, for example which files it uses
DATA DIVISIONDeclares all data: file records, working storage, parameters
PROCEDURE DIVISIONThe executable statements, organized into paragraphs

Every variable must be declared in the DATA DIVISION before use. The WORKING-STORAGE SECTION holds the program's variables, the FILE SECTION describes file records, and the LINKAGE SECTION describes parameters passed by a caller.

Data and PIC clauses

COBOL describes data by its exact layout. A level number shows the hierarchy (01 is a record, 05 a field inside it), and a PIC clause gives the format: X is any character, 9 is a digit, S a sign, and V an implied decimal point.

DeclarationMeaningExample value
PIC X(10)10 characters, padded with spaces"Ana "
PIC 9(3)Unsigned 3-digit number030
PIC S9(5)V99Signed, 5 digits before and 2 after the decimal point-01234.50
PIC $ZZ,ZZ9.99Edited output: currency sign, leading zeros as spaces$ 1,234.50
PIC S9(7)V99 COMP-3Packed decimal, common on mainframesstored in 5 bytes
88 IS-DONE VALUE "Y"Condition name: a Boolean test on its parent fieldIF IS-DONE
       IDENTIFICATION DIVISION.
       PROGRAM-ID. DATA-DEMO.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-NAME        PIC X(10)      VALUE "Ana".
       01  WS-AGE         PIC 9(3)       VALUE 30.
       01  WS-PRICE       PIC S9(5)V99   VALUE 1234.50.
       01  WS-PRICE-OUT   PIC $ZZ,ZZ9.99.
       01  WS-CUSTOMER.
           05  WS-FIRST   PIC X(10).
           05  WS-LAST    PIC X(15).
       PROCEDURE DIVISION.
           MOVE WS-PRICE TO WS-PRICE-OUT
           DISPLAY WS-NAME "is " WS-AGE
           DISPLAY "Price: " WS-PRICE-OUT
           STOP RUN.
      *> Ana       is 030
      *> Price: $ 1,234.50

Numbers are stored in decimal, so 0.10 + 0.20 is exactly 0.30, which is one reason COBOL suits money. WS-CUSTOMER is a group item: it can be moved as a whole or field by field.

Control flow: IF, EVALUATE and PERFORM

       IDENTIFICATION DIVISION.
       PROGRAM-ID. CONTROL-DEMO.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-I        PIC 99.
       01  WS-TOTAL    PIC 9(4) VALUE 0.
       01  WS-SCORE    PIC 999  VALUE 85.
       PROCEDURE DIVISION.
           PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10
               ADD WS-I TO WS-TOTAL
           END-PERFORM
           DISPLAY "Total: " WS-TOTAL
           EVALUATE TRUE
               WHEN WS-SCORE >= 90
                   DISPLAY "A"
               WHEN WS-SCORE >= 80
                   DISPLAY "B"
               WHEN OTHER
                   DISPLAY "C"
           END-EVALUATE
           IF WS-TOTAL > 50
               DISPLAY "big"
           ELSE
               DISPLAY "small"
           END-IF
           STOP RUN.
      *> Total: 0055
      *> B
      *> big

PERFORM VARYING is COBOL's counting loop and PERFORM UNTIL condition its while loop. EVALUATE is a switch statement. Scope terminators such as END-IF and END-PERFORM close each block; a period ends the whole sentence.

Paragraphs, arithmetic and tables

COBOL has no functions in the usual sense. You organize logic into named paragraphs and run them with PERFORM; larger units become separate programs called with CALL "PROG" USING .... Arithmetic uses verbs (ADD, SUBTRACT, MULTIPLY, DIVIDE) or COMPUTE with a formula. Arrays are called tables and are declared with OCCURS; their indexes start at 1.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PARA-DEMO.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-PRICES.
           05  WS-PRICE   PIC 9(3)V99 OCCURS 3 TIMES.
       01  WS-I           PIC 9.
       01  WS-SUM         PIC 9(4)V99 VALUE 0.
       01  WS-SUM-OUT     PIC Z,ZZ9.99.
       PROCEDURE DIVISION.
       MAIN-PARA.
           MOVE 10.50 TO WS-PRICE(1)
           MOVE 4.25  TO WS-PRICE(2)
           MOVE 7.00  TO WS-PRICE(3)
           PERFORM ADD-PRICE VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 3
           COMPUTE WS-SUM = WS-SUM * 1.1
           MOVE WS-SUM TO WS-SUM-OUT
           DISPLAY "With 10% tax: " WS-SUM-OUT
           STOP RUN.
       ADD-PRICE.
           ADD WS-PRICE(WS-I) TO WS-SUM.
      *> With 10% tax:    23.92

The sum is 21.75; multiplied by 1.1 it is 23.925, and COBOL truncates to the two declared decimals (23.92) unless you write COMPUTE ... ROUNDED.

Error handling

COBOL has no exceptions in everyday code. Instead, statements have conditional phrases: ON SIZE ERROR for arithmetic overflow or division by zero, AT END for the end of a file, INVALID KEY for indexed files, and a FILE STATUS field that receives a two-character code after every file operation ("00" means success).

           DIVIDE WS-A BY WS-B GIVING WS-C
               ON SIZE ERROR
                   DISPLAY "Division failed"
               NOT ON SIZE ERROR
                   DISPLAY "Result: " WS-C
           END-DIVIDE

A small complete program: total of a sales file

Reading fixed-layout records from a file is typical COBOL work. This program reads sales.txt, where each line has a 10-character item name followed by a 7-digit amount with two implied decimals.

apples    0001250
pears     0000899
plums     0002000
       IDENTIFICATION DIVISION.
       PROGRAM-ID. SALES-TOTAL.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT SALES-FILE ASSIGN TO "sales.txt"
               ORGANIZATION IS LINE SEQUENTIAL
               FILE STATUS IS WS-FS.
       DATA DIVISION.
       FILE SECTION.
       FD  SALES-FILE.
       01  SALES-REC.
           05  SR-ITEM     PIC X(10).
           05  SR-AMOUNT   PIC 9(5)V99.
       WORKING-STORAGE SECTION.
       01  WS-FS           PIC XX.
       01  WS-EOF          PIC X VALUE "N".
           88  NO-MORE-RECORDS       VALUE "Y".
       01  WS-TOTAL        PIC 9(7)V99 VALUE 0.
       01  WS-TOTAL-OUT    PIC Z,ZZZ,ZZ9.99.
       PROCEDURE DIVISION.
           OPEN INPUT SALES-FILE
           IF WS-FS NOT = "00"
               DISPLAY "Cannot open file, status " WS-FS
               STOP RUN
           END-IF
           PERFORM UNTIL NO-MORE-RECORDS
               READ SALES-FILE
                   AT END SET NO-MORE-RECORDS TO TRUE
                   NOT AT END ADD SR-AMOUNT TO WS-TOTAL
               END-READ
           END-PERFORM
           CLOSE SALES-FILE
           MOVE WS-TOTAL TO WS-TOTAL-OUT
           DISPLAY "Total sales: " WS-TOTAL-OUT
           STOP RUN.

Running it prints Total sales: followed by 41.49 right-aligned in the 12-character edited field. LINE SEQUENTIAL means a text file with one record per line; it is supported by GnuCOBOL and other PC compilers, while mainframe programs usually read fixed-length datasets defined in JCL.

Where to go next

  • The GnuCOBOL project pages and its Programmer's Guide for a full language reference.
  • IBM's Enterprise COBOL for z/OS documentation for mainframe COBOL, CICS and Db2 usage.
  • Practice reading and writing files, sorting with the SORT verb, and producing formatted reports.
  • Learn the surrounding mainframe tools (JCL, TSO/ISPF) if you want to work on production systems.

FAQ

Is COBOL still used?

Yes. Many banks, insurers and government agencies still run COBOL programs for core batch and transaction processing, so there is ongoing demand for developers who can maintain and modernize them.

Is COBOL hard to learn?

The syntax is verbose but simple, and most beginners can write working programs quickly. The harder part is the mainframe environment around it: JCL, datasets, CICS and Db2.

Can I learn COBOL without a mainframe?

Yes. GnuCOBOL runs on Linux, macOS and Windows and supports standard COBOL, so you can learn the language on a normal computer before moving to a mainframe.

Why does COBOL use decimal numbers?

Business data such as money must be exact. COBOL stores numbers as decimal digits with a fixed number of decimal places, which avoids the rounding errors of binary floating point.

All coding tutorials