> "A computer is only as useful as the information it can communicate. Before a COBOL program can process files, generate reports, or update databases, it must first master the fundamentals of sending output to a screen and receiving input from a...
In This Chapter
Chapter 5: Basic Input/Output and DISPLAY/ACCEPT Statements
"A computer is only as useful as the information it can communicate. Before a COBOL program can process files, generate reports, or update databases, it must first master the fundamentals of sending output to a screen and receiving input from a user."
Chapter Objectives
After completing this chapter, you will be able to:
- Use the DISPLAY statement to send output to the console in multiple formats
- Accept user input with the ACCEPT statement in interactive programs
- Retrieve system date, time, and environment information using ACCEPT
- Build formatted console output using edited PICTURE clauses and record structures
- Use the STRING statement to concatenate fields for dynamic output
- Create screen layouts using the SCREEN SECTION (COBOL 2002 / GnuCOBOL)
- Design menu-driven interactive programs with input validation
- Understand the differences between batch and interactive I/O patterns
- Distinguish between IBM mainframe I/O conventions and GnuCOBOL capabilities
5.1 Console I/O: The Foundation Before File I/O
Every COBOL program you have written so far has used the DISPLAY statement to show results on the screen. Every program that has asked for user input has used the ACCEPT statement. These two statements form the most basic input/output mechanism in COBOL, and they deserve thorough examination before we move on to file-based I/O in Part III.
Console I/O -- communicating with the terminal or system console -- serves several critical purposes in COBOL programming:
-
Debugging and diagnostics. Before sophisticated debugging tools existed, DISPLAY statements were (and still are) the primary way COBOL programmers trace program execution and inspect variable values.
-
Operator communication. In batch mainframe environments, DISPLAY UPON CONSOLE sends messages to the system operator, reporting job status or requesting intervention.
-
Interactive programs. While less common in traditional mainframe COBOL, interactive terminal programs use DISPLAY and ACCEPT extensively for user-facing applications.
-
Prototyping. Before building full file-based or database-driven applications, developers prototype business logic using console I/O for rapid testing.
In this chapter, we will explore both statements in depth, learning not just the syntax but the patterns and practices that professional COBOL programmers use daily.
5.2 The DISPLAY Statement
The DISPLAY statement is the primary mechanism for sending output from a COBOL program to an output device -- typically the console or terminal screen.
5.2.1 Basic Syntax
The general format of the DISPLAY statement is:
DISPLAY {identifier-1 | literal-1} ...
[UPON {CONSOLE | SYSOUT | mnemonic-name}]
[WITH NO ADVANCING]
[END-DISPLAY]
Let us examine each component.
5.2.2 Displaying Literals
The simplest use of DISPLAY outputs a literal string:
DISPLAY "Hello, World!"
DISPLAY "Welcome to COBOL programming."
Each DISPLAY statement produces one line of output, followed by a carriage return and line feed (a new line). Successive DISPLAY statements produce successive lines:
DISPLAY "Line 1"
DISPLAY "Line 2"
DISPLAY "Line 3"
Output:
Line 1
Line 2
Line 3
You can display numeric literals as well:
DISPLAY 42
DISPLAY 3.14159
COBOL also supports figurative constants in DISPLAY statements:
DISPLAY SPACES *> Displays a blank line
DISPLAY ALL "*" *> Fills the line with asterisks
DISPLAY ALL "=-" *> Repeats "=-" pattern across the line
The DISPLAY SPACES idiom is commonly used to insert blank lines between sections of output for readability.
5.2.3 Displaying Identifiers (Variables)
When you display a variable (called an identifier in COBOL terminology), the entire content of the field is shown, including any padding:
01 WS-NAME PIC X(20) VALUE "GRACE HOPPER".
01 WS-AGE PIC 9(3) VALUE 85.
DISPLAY WS-NAME
DISPLAY WS-AGE
Output:
GRACE HOPPER
085
Notice two important behaviors:
- Alphanumeric fields (PIC X) are displayed with their full width, including trailing spaces. The name "GRACE HOPPER" is followed by 8 spaces to fill the 20-character field.
- Numeric fields (PIC 9) display with leading zeros. The value 85 in a PIC 9(3) field displays as "085".
This behavior is fundamental to understanding COBOL output. The DISPLAY statement shows the storage representation of the field, not a "pretty-printed" version. To format numbers for human consumption, you must use edited PICTURE clauses, which we cover in Section 5.7.
5.2.4 Concatenating Multiple Items
One of the most useful features of the DISPLAY statement is its ability to concatenate multiple items on a single line. Simply list the items one after another:
DISPLAY "Name: " WS-NAME
DISPLAY "Employee " WS-FIRST-NAME " " WS-LAST-NAME
DISPLAY "Age: " WS-AGE " years old"
The items are concatenated directly with no automatic spacing between them. This is both a feature and a source of common errors. Because alphanumeric fields carry their trailing spaces, the output can look awkward:
01 WS-FIRST PIC X(15) VALUE "GRACE".
01 WS-LAST PIC X(15) VALUE "HOPPER".
DISPLAY WS-FIRST WS-LAST
Output:
GRACE HOPPER
The 10 trailing spaces in WS-FIRST appear between the two names. To avoid this, you can use the STRING statement (Section 5.8) or FUNCTION TRIM (available in COBOL 2014 and GnuCOBOL).
You can mix literals, identifiers, and figurative constants in a single DISPLAY:
DISPLAY "Employee: " WS-NAME " | ID: " WS-EMP-ID
In fixed-format COBOL, when a DISPLAY statement is too long for a single line (columns 12-72), you can continue on the next line by placing the continuation in Area B:
DISPLAY "Employee " WS-FIRST-NAME " "
WS-LAST-NAME " works in "
WS-DEPARTMENT
The compiler treats all items listed before the period (or END-DISPLAY) as part of one DISPLAY operation.
See:
code/example-01-display.cobfor a complete demonstration of literal, variable, and concatenated DISPLAY statements.
5.2.5 WITH NO ADVANCING
By default, each DISPLAY statement outputs a line followed by a carriage return and line feed. The WITH NO ADVANCING clause suppresses the line terminator, keeping the cursor on the same line:
DISPLAY "Enter your name: " WITH NO ADVANCING
ACCEPT WS-NAME
This is essential for creating prompts where you want the user's input to appear on the same line as the prompt text:
Enter your name: John Smith
Without WITH NO ADVANCING, the cursor would move to the next line before waiting for input:
Enter your name:
John Smith
You can chain multiple WITH NO ADVANCING displays to build up a line incrementally:
DISPLAY "Loading: [" WITH NO ADVANCING
DISPLAY "=====" WITH NO ADVANCING
DISPLAY "=====" WITH NO ADVANCING
DISPLAY "] 100%"
Output:
Loading: [==========] 100%
The final DISPLAY without WITH NO ADVANCING terminates the line.
Important
The behavior of WITH NO ADVANCING can vary between compilers and environments. In IBM batch COBOL, DISPLAY goes to SYSOUT by default, and WITH NO ADVANCING may not behave as expected because SYSOUT is a sequential dataset, not an interactive terminal. WITH NO ADVANCING works reliably in interactive (terminal) contexts with GnuCOBOL and in CICS environments.
5.2.6 DISPLAY UPON CONSOLE vs UPON SYSOUT
The UPON clause specifies the output destination:
DISPLAY "Message to console" UPON CONSOLE
DISPLAY "Message to SYSOUT" UPON SYSOUT
The distinction between these destinations is primarily relevant on IBM mainframes:
| Destination | IBM Mainframe Behavior | GnuCOBOL Behavior |
|---|---|---|
| (default, no UPON) | SYSOUT DD in JCL | stdout (terminal) |
| UPON CONSOLE | Operator console (WTOR/WTO) | stdout (terminal) |
| UPON SYSOUT | SYSOUT DD in JCL | stdout (terminal) |
IBM-specific details:
DISPLAY UPON SYSOUTsends output to the SYSOUT DD statement in the JCL, which typically goes to a spool dataset that the programmer can review after the job completes.DISPLAY UPON CONSOLEsends a Write-To-Operator (WTO) message to the z/OS system console. This is used for operator communication in production batch jobs (for example, "WAITING FOR TAPE MOUNT" or "JOB COMPLETED SUCCESSFULLY").- In IBM Enterprise COBOL, the default destination for a DISPLAY statement (without UPON) is SYSOUT.
GnuCOBOL behavior:
In GnuCOBOL, all three forms -- DISPLAY, DISPLAY UPON CONSOLE, and DISPLAY UPON SYSOUT -- send output to stdout (the terminal). The distinction is syntactically accepted but functionally equivalent.
Best practice: For portable code, use plain DISPLAY for general output. Reserve UPON CONSOLE or UPON SYSOUT only when you specifically need mainframe-specific routing.
5.3 The ACCEPT Statement
While DISPLAY sends data out of the program, ACCEPT brings data into the program. The ACCEPT statement is more versatile than it first appears, supporting both interactive user input and system information retrieval.
5.3.1 Basic Syntax
ACCEPT identifier-1
[FROM {CONSOLE | SYSIN | mnemonic-name |
DATE [YYYYMMDD] | DAY [YYYYDDD] |
TIME | DAY-OF-WEEK |
ENVIRONMENT-NAME | ENVIRONMENT-VALUE |
COMMAND-LINE}]
[END-ACCEPT]
5.3.2 ACCEPT FROM CONSOLE (Interactive Input)
The most basic form of ACCEPT reads a line of input from the user:
01 WS-USER-NAME PIC X(30).
DISPLAY "Enter your name: " WITH NO ADVANCING
ACCEPT WS-USER-NAME
When the program reaches the ACCEPT statement, execution pauses and the cursor waits for the user to type input and press Enter. The entered text is stored in the receiving field according to standard COBOL MOVE rules:
- If the input is shorter than the field, it is left-justified and padded with spaces on the right (for alphanumeric fields).
- If the input is longer than the field, it is truncated on the right (for alphanumeric fields).
- For numeric fields (PIC 9), the input is right-justified and padded with leading zeros.
01 WS-NAME PIC X(10).
ACCEPT WS-NAME *> User types "JOHN"
*> WS-NAME now contains "JOHN " (padded with 6 spaces)
ACCEPT WS-NAME *> User types "CHRISTOPHER"
*> WS-NAME now contains "CHRISTOPHE" (truncated to 10 chars)
Accepting numeric input:
When accepting into a numeric field, COBOL expects the user to type digits:
01 WS-AGE PIC 9(3).
DISPLAY "Enter your age: " WITH NO ADVANCING
ACCEPT WS-AGE
If the user types "25", WS-AGE will contain "025" (right-justified with a leading zero). If the user types non-numeric characters into a PIC 9 field, the behavior is undefined and may cause data exceptions in subsequent arithmetic operations.
Best practice: For robust programs, accept user input into an alphanumeric field (PIC X), validate it, and then move it to a numeric field. This prevents abends from invalid input.
01 WS-INPUT PIC X(10).
01 WS-AGE PIC 9(3).
DISPLAY "Enter your age: " WITH NO ADVANCING
ACCEPT WS-INPUT
IF WS-INPUT IS NUMERIC
MOVE WS-INPUT TO WS-AGE
ELSE
DISPLAY "Invalid input. Please enter digits."
END-IF
5.3.3 ACCEPT FROM CONSOLE vs Default ACCEPT
On IBM mainframes, the default source for ACCEPT (without a FROM clause) is the SYSIN DD statement in JCL, which reads from a dataset or inline data. To read from the operator console, you must specify ACCEPT ... FROM CONSOLE.
In GnuCOBOL, the default source is the terminal (stdin), so ACCEPT and ACCEPT FROM CONSOLE are functionally equivalent.
| Source | IBM Mainframe | GnuCOBOL |
|---|---|---|
| (default) | SYSIN DD | stdin (terminal) |
| FROM CONSOLE | Operator console | stdin (terminal) |
| FROM SYSIN | SYSIN DD | stdin (terminal) |
See:
code/example-02-accept.cobfor a complete demonstration of interactive ACCEPT statements.
5.4 Accepting System Information
One of the most powerful features of the ACCEPT statement is its ability to retrieve system information without any user interaction. This is indispensable for timestamping records, generating date-based report headers, and implementing date-sensitive business logic.
5.4.1 ACCEPT FROM DATE
01 WS-DATE-YYMMDD PIC 9(6).
01 WS-DATE-YYYYMMDD PIC 9(8).
ACCEPT WS-DATE-YYMMDD FROM DATE
ACCEPT WS-DATE-YYYYMMDD FROM DATE YYYYMMDD
The two-digit year DATE format returns YYMMDD (for example, 260210 for February 10, 2026). The four-digit year DATE YYYYMMDD returns YYYYMMDD (for example, 20260210).
Critical warning: Always use
DATE YYYYMMDD. The two-digit year format was a central cause of the Y2K crisis. It is retained only for backward compatibility. New programs should never use the two-digit form.
To work with individual date components, use a REDEFINES:
01 WS-CURRENT-DATE PIC 9(8).
01 WS-DATE-PARTS REDEFINES WS-CURRENT-DATE.
05 WS-YEAR PIC 9(4).
05 WS-MONTH PIC 9(2).
05 WS-DAY PIC 9(2).
ACCEPT WS-CURRENT-DATE FROM DATE YYYYMMDD
DISPLAY "Year: " WS-YEAR
DISPLAY "Month: " WS-MONTH
DISPLAY "Day: " WS-DAY
5.4.2 ACCEPT FROM TIME
01 WS-TIME-VALUE PIC 9(8).
01 WS-TIME-PARTS REDEFINES WS-TIME-VALUE.
05 WS-HOURS PIC 9(2).
05 WS-MINUTES PIC 9(2).
05 WS-SECONDS PIC 9(2).
05 WS-HUNDREDTHS PIC 9(2).
ACCEPT WS-TIME-VALUE FROM TIME
The TIME value is an 8-digit number in the format HHMMSSss:
- HH: Hours (00-23) in 24-hour format
- MM: Minutes (00-59)
- SS: Seconds (00-59)
- ss: Hundredths of a second (00-99)
For example, 14305075 represents 2:30:50.75 PM.
5.4.3 ACCEPT FROM DAY (Julian Date)
01 WS-JULIAN-SHORT PIC 9(5).
01 WS-JULIAN-LONG PIC 9(7).
ACCEPT WS-JULIAN-SHORT FROM DAY *> YYDDD
ACCEPT WS-JULIAN-LONG FROM DAY YYYYDDD *> YYYYDDD
The Julian date represents the day as a day-of-year number (001-365 or 366 for leap years). For example, February 10, 2026 is day 041, so the Julian date would be 2026041.
Julian dates are commonly used in mainframe batch processing because they simplify date arithmetic -- you can calculate the number of days between two dates by simple subtraction when the dates are in the same year.
5.4.4 ACCEPT FROM DAY-OF-WEEK
01 WS-DOW PIC 9.
ACCEPT WS-DOW FROM DAY-OF-WEEK
Returns a single digit following the ISO 8601 convention:
| Value | Day |
|---|---|
| 1 | Monday |
| 2 | Tuesday |
| 3 | Wednesday |
| 4 | Thursday |
| 5 | Friday |
| 6 | Saturday |
| 7 | Sunday |
A common pattern is to use EVALUATE to convert this number into a day name:
01 WS-DOW PIC 9.
01 WS-DAY-NAME PIC X(9).
ACCEPT WS-DOW FROM DAY-OF-WEEK
EVALUATE WS-DOW
WHEN 1 MOVE "Monday" TO WS-DAY-NAME
WHEN 2 MOVE "Tuesday" TO WS-DAY-NAME
WHEN 3 MOVE "Wednesday" TO WS-DAY-NAME
WHEN 4 MOVE "Thursday" TO WS-DAY-NAME
WHEN 5 MOVE "Friday" TO WS-DAY-NAME
WHEN 6 MOVE "Saturday" TO WS-DAY-NAME
WHEN 7 MOVE "Sunday" TO WS-DAY-NAME
END-EVALUATE
An alternative approach using a table lookup is more concise and is demonstrated in code/example-06-date-time.cob.
See:
code/example-06-date-time.cobfor comprehensive date and time formatting, including ISO, US, European, and long-format dates, 12-hour and 24-hour times, timestamps, and leap year detection.
5.4.5 ACCEPT FROM DATE YYYYMMDD vs DATE (The Y2K Lesson)
The two-digit year format ACCEPT FROM DATE exists because COBOL was designed in 1959, when storage was expensive and a two-digit year seemed adequate. When the year 2000 approached, billions of dollars were spent modifying programs that could not distinguish between 1900 and 2000.
The four-digit format ACCEPT FROM DATE YYYYMMDD was introduced in COBOL-85 amendments and is standard in COBOL 2002. It should be used exclusively in all new development.
Consider this contrast:
* DANGEROUS -- Y2K-vulnerable
01 WS-OLD-DATE PIC 9(6).
ACCEPT WS-OLD-DATE FROM DATE
* Returns 260210 -- is this 2026 or 1926?
* SAFE -- Y2K-compliant
01 WS-NEW-DATE PIC 9(8).
ACCEPT WS-NEW-DATE FROM DATE YYYYMMDD
* Returns 20260210 -- unambiguous
5.4.6 ACCEPT FROM ENVIRONMENT-NAME / ENVIRONMENT-VALUE
COBOL can read operating system environment variables. The standard COBOL 2002 mechanism uses a two-step process:
01 WS-ENV-NAME PIC X(30).
01 WS-ENV-VALUE PIC X(256).
* Step 1: Set the environment variable name
MOVE "PATH" TO WS-ENV-NAME
DISPLAY WS-ENV-NAME UPON ENVIRONMENT-NAME
* Step 2: Accept the value
ACCEPT WS-ENV-VALUE FROM ENVIRONMENT-VALUE
GnuCOBOL provides a more concise syntax:
ACCEPT WS-ENV-VALUE FROM ENVIRONMENT "HOME"
This is useful for configuration-driven programs that read database connection strings, file paths, or runtime parameters from the environment rather than hardcoding them.
5.4.7 ACCEPT FROM COMMAND-LINE (GnuCOBOL)
GnuCOBOL extends the ACCEPT statement to read command-line arguments:
01 WS-CMD-LINE PIC X(256).
ACCEPT WS-CMD-LINE FROM COMMAND-LINE
This reads the entire command line that was used to invoke the program. For more fine-grained argument parsing, GnuCOBOL also provides:
01 WS-ARG-COUNT PIC 9(4).
01 WS-ARG-VALUE PIC X(100).
ACCEPT WS-ARG-COUNT FROM ARGUMENT-NUMBER
ACCEPT WS-ARG-VALUE FROM ARGUMENT-VALUE
Note
Command-line argument handling is a GnuCOBOL extension. IBM Enterprise COBOL does not support this; mainframe programs receive parameters through JCL PARM fields or SYSIN datasets.
5.5 Building Formatted Output
Raw DISPLAY output with unedited PIC 9 and PIC X fields looks mechanical and difficult to read. Professional COBOL programs invest significant effort in formatting output for human consumption. This section covers the primary techniques.
5.5.1 Edited PICTURE Clauses for Display
We introduced PICTURE clauses in Chapter 3. Edited pictures transform numeric data into human-readable formats by inserting currency signs, commas, decimal points, and suppressing leading zeros.
The most common edited picture symbols for display:
| Symbol | Purpose | Example PIC | Input | Output |
|---|---|---|---|---|
Z |
Zero suppression (replace leading 0 with space) | ZZZ,ZZ9 |
001234 | 1,234 |
| `$` | Currency sign (floating) | ` MATH0 $,$$9.99` | 12345.67 | ` $12,345.67` | | `,` | Comma insertion | `999,999` | 123456 | `123,456` | | `.` | Decimal point | `999.99` | 12345 | `123.45` | | `-` | Floating minus sign | `-(5)9.99` | -1234.56 | ` -1234.56` | | `+` | Floating plus/minus sign | `+(5)9.99` | 1234.56 | ` +1234.56` | | `*` | Check protection (fill with asterisks) | `**,***,**9.99` | 1234.56 | `*****1,234.56` | | `CR` | Credit symbol (for negative) | `9(5).99CR` | -123.45 | `00123.45CR` | | `DB` | Debit symbol (for negative) | `9(5).99DB` | -123.45 | `00123.45DB` | The pattern for formatted display is always the same: 1. Define the edited picture field in WORKING-STORAGE. 2. MOVE the numeric value to the edited field. 3. DISPLAY the edited field. ```cobol 01 WS-SALARY PIC 9(7)V99 VALUE 125000.50. 01 WS-SALARY-EDITED PIC $$$,$$$,$$9.99. |
MOVE WS-SALARY TO WS-SALARY-EDITED
DISPLAY "Salary: " WS-SALARY-EDITED
Output:
Salary: $125,000.50
Compare this with the raw display:
```cobol
DISPLAY "Salary: " WS-SALARY
Output:
Salary: 012500050
The difference is dramatic. Edited pictures are essential for any program that produces output meant for humans.
5.5.2 Structured Record Lines for Columnar Output
For tabular or report-style output, COBOL programmers define record structures in WORKING-STORAGE that represent one complete line of output. Each field in the record corresponds to a column, and FILLER items provide spacing:
``cobol
01 WS-DETAIL-LINE.
05 FILLER PIC X(2) VALUE SPACES.
05 WS-DET-ID PIC 9(6).
05 FILLER PIC X(3) VALUE SPACES.
05 WS-DET-NAME PIC X(25).
05 FILLER PIC X(3) VALUE SPACES.
05 WS-DET-SALARY PIC $$$,$$$, MATH4 , MATH5 9.99` | 12345.67 | ` $12,345.67 |
| -(5)9.99 | -1234.56 | -1234.56 |
| Z(5)9 | 000042 | 42 |
In the next chapter, we move from I/O to computation, exploring COBOL's arithmetic statements: ADD, SUBTRACT, MULTIPLY, DIVIDE, and COMPUTE. Together with the I/O skills from this chapter, arithmetic operations will enable you to build programs that process and transform data -- the core mission of COBOL.