Welcome back. In our previous lesson, we conducted a rapid review of COBOL's structure and its DATA DIVISION, re-establishing the foundation of how data is defined. Now, we shift our focus from defining data to actively manipulating it within the PROCEDURE DIVISION.
This lesson addresses three critical areas of COBOL programming that are hallmarks of a senior developer's skill set and frequent topics in technical interviews. We will cover:
- Advanced file handling, focusing on robust error checking using the
FILE STATUSclause. - Powerful string manipulation with the
STRING,UNSTRING, andINSPECTverbs. - The use of intrinsic functions to write cleaner, more modern, and efficient code.
Mastery of these concepts is essential for building resilient batch programs and services that can gracefully handle the imperfect data and unexpected I/O conditions common in production environments.
Building Robust I/O with Advanced File Handling
In any production system, assuming every READ or WRITE operation will succeed is a recipe for failure. A senior developer is expected to write code that anticipates and correctly handles I/O errors. COBOL provides several mechanisms for this, but the most comprehensive is the FILE STATUS clause.
When you declare a file in the FILE-CONTROL paragraph of your ENVIRONMENT DIVISION, you can associate it with a two-byte data item. After every I/O operation on that file, COBOL updates this field with a status code.
Here's an example of the declaration:
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT-FILE ASSIGN TO INFILE
FILE STATUS IS WS-INFILE-STATUS.
...
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-INFILE-STATUS PIC XX.
88 INFILE-OK VALUE '00'.
88 INFILE-EOF VALUE '10'.
The FILE STATUS key is your program's window into the outcome of an I/O request. A value of '00' indicates success. '10' indicates an end-of-file condition on a sequential read. Any other value signals a warning or an error that your program must handle.
IBM's documentation provides a concise overview of the different error handling techniques available in COBOL.
Handling errors in input and output operations - IBM
This document from IBM outlines the primary methods for intercepting and managing I/O errors in COBOL.
Read the initial overview to see the list of available techniques. Then, examine the two flowcharts that illustrate the logical flow after an I/O error for VSAM and QSAM files. These diagrams show how your error-handling logic (like checking the file status key) fits into the overall process.
As the documentation highlights, you have several tools at your disposal:
AT END: Used in aREADstatement for sequential files. This is the standard way to detect the end of a file and exit a read loop.INVALID KEY: Used with indexed (KSDS) or relative (RRDS) files for operations likeREAD,WRITE,REWRITE, andDELETE. This phrase is triggered by key-related errors, such as:- Attempting to
WRITEa record with a key that already exists. - Attempting to
READorDELETEa record with a key that does not exist. - Sequence errors when loading an indexed file.
- Attempting to
FILE STATUSchecking: This is the most versatile method. By checking the value of your file status variable after each I/O verb, you can diagnose a wide range of issues. For example:'23': Record not found for a KSDS file (often handled byINVALID KEYbut also reported here).'35': File not found (aDDstatement might be missing in the JCL).'39': A mismatch between the file definition (FD) and the actual file attributes (e.g., wrongRECORD CONTAINSlength).'9x': Serious VSAM or system-level errors.
In an interview, being able to discuss specific file status codes and how you would code routines to handle them demonstrates a deep understanding of building resilient applications.
Powerful String Manipulation: STRING, UNSTRING, and INSPECT
Raw data rarely arrives in the exact format you need. COBOL provides three powerful verbs for parsing, concatenating, and transforming string data.
Concatenating with STRING
The STRING verb is used to combine multiple data items into a single destination field. It is far more flexible than simple MOVE statements, allowing you to specify delimiters and stop concatenation based on specific conditions.
A common use case is building a delimited record (like a CSV line) or formatting a line for a report. The WITH POINTER clause is crucial for managing the current position within the destination field, preventing overwrites.

Parsing with UNSTRING
The UNSTRING verb is the inverse of STRING. It deconstructs a single string into multiple destination fields based on one or more delimiters. This is invaluable for parsing data from external sources, such as comma-separated values or space-delimited fields.
UNSTRING offers fine-grained control with clauses like:
DELIMITED BY: Specifies the character(s) that separate the fields.INTO: The list of receiving fields.COUNT IN: Stores the number of characters moved into a receiving field.TALLYING IN: Stores the total number of receiving fields that were populated.

Analyzing with INSPECT
While STRING and UNSTRING move data, INSPECT analyzes data in place. It can be used to count occurrences of specific characters or to replace them.
Common uses for INSPECT include:
- Data Validation: Using
TALLYINGto count non-numeric or invalid characters in a field before a calculation.INSPECT WS-INPUT-FIELD TALLYING WS-NON-NUMERIC-COUNT FOR ALL CHARACTERS BEFORE INITIAL '0'. - Data Cleansing: Using
REPLACINGto change leading spaces to zeros or to convert lowercase letters to uppercase.INSPECT WS-PRODUCT-CODE REPLACING LEADING ' ' BY '0'. - Pre-processing for
UNSTRING: Counting delimiters in a source string to ensure it has the expected number of fields before attempting to parse it.
These three verbs are the core toolkit for handling the complex data formatting and re-formatting tasks that are ubiquitous in batch processing.
Leveraging Intrinsic Functions
Modern COBOL standards have introduced a rich library of intrinsic functions that can significantly simplify code, improve readability, and reduce the need to write complex, error-prone procedural logic. As a senior developer, you are expected to know and use these functions where appropriate.
Here are a few essential functions grouped by purpose:
Date and Time Functions
FUNCTION CURRENT-DATE: Returns a 21-character string containing the system date, time, and timezone offset. You typically move this to a group item to parse its components.FUNCTION DATE-OF-INTEGER(integer-date): Converts an integer date (days since Dec 31, 1600) to YYYYMMDD format.FUNCTION INTEGER-OF-DATE(yyyymmdd-date): The inverse, converting a YYYYMMDD date to an integer for calculations.
String and Character Functions
FUNCTION TRIM(source-string): Returns the source string with trailing spaces removed. Extremely useful for cleaning up data.FUNCTION LENGTH(data-item): Returns the length in bytes of a data item. Useful for dynamically handling variable-length fields.FUNCTION UPPER-CASE(string)andFUNCTION LOWER-CASE(string): Convert a string's case, which is useful for case-insensitive comparisons.
Numeric and Conversion Functions
FUNCTION NUMVAL(string): Converts an alphanumeric string containing a number into a numeric value. It handles leading/trailing signs and spaces.FUNCTION NUMVAL-C(string): Similar toNUMVAL, but also handles currency symbols, commas, and decimal points. Indispensable when working with formatted report data.MOVE FUNCTION NUMVAL-C("$1,234.56CR") TO WS-AMOUNT. *> WS-AMOUNT would now hold -1234.56FUNCTION SQRT(number): Calculates the square root.
Using these functions not only makes your code more concise but also signals that your knowledge of COBOL is current.
Conclusion
In this lesson, we have moved beyond data definition to data manipulation, a critical step in building functional and robust programs. You should now be comfortable with:
- Robust I/O Handling: The central role of the
FILE STATUSclause in trapping and diagnosing file errors, supplemented byAT ENDandINVALID KEYfor specific conditions. - String Manipulation Verbs: The distinct purposes of
STRING(to build),UNSTRING(to parse), andINSPECT(to analyze and transform) strings. - Intrinsic Functions: How to use key built-in functions to simplify common tasks related to dates, strings, and numeric conversions, leading to more modern and maintainable code.
These skills form the core of procedural logic in COBOL. In our next lesson, we will build upon this by exploring how to structure that logic into reusable modules. We will dive into advanced subprogram patterns, analyzing the trade-offs between static and dynamic CALL statements and the different methods of passing data between programs.