Chapter 9 Exercises: String Handling and Character Manipulation
Tier 1: Fundamentals (Exercises 1-8)
These exercises cover basic usage of STRING, UNSTRING, INSPECT, and reference modification. If you are new to COBOL string handling, start here.
Exercise 1: Name Concatenation
Write a COBOL paragraph that takes the following fields and produces a formatted full name in "LAST, FIRST MIDDLE" format:
01 WS-FIRST PIC X(15) VALUE "JANE".
01 WS-MIDDLE PIC X(15) VALUE "MARIE".
01 WS-LAST PIC X(20) VALUE "ROBERTSON".
01 WS-RESULT PIC X(50).
Expected output: "ROBERTSON, JANE MARIE"
Use the STRING statement with appropriate DELIMITED BY clauses. Do not include trailing spaces from any source field.
Exercise 2: Date Reformatting
Given a date in YYYYMMDD format, produce the date in MM/DD/YYYY format using reference modification and STRING:
01 WS-DATE-IN PIC X(08) VALUE "20240725".
01 WS-DATE-OUT PIC X(10).
Expected output: "07/25/2024"
Exercise 3: CSV Field Counting
Write code that parses the following CSV string and counts the total number of fields using UNSTRING with TALLYING IN:
01 WS-CSV PIC X(80)
VALUE "RED,GREEN,BLUE,YELLOW,ORANGE,PURPLE,BROWN".
Display each field and the total field count.
Expected output: 7 fields parsed.
Exercise 4: Character Counting with INSPECT
Using INSPECT TALLYING, count the following in the string "PROGRAMMING IN COBOL IS POWERFUL":
- The number of spaces
- The number of occurrences of the letter "O"
- The total number of vowels (A, E, I, O, U)
Display each count.
Exercise 5: Vowels vs. Consonants
Extend Exercise 4 to calculate the number of consonants (non-vowel, non-space alphabetic characters). Display the counts for vowels, consonants, and spaces.
Hint: Total alphabetic characters minus vowels equals consonants.
Exercise 6: Leading Zero Removal
Write code using INSPECT REPLACING LEADING to convert "00000125.50" to " 125.50" (replace leading zeros with spaces):
01 WS-AMOUNT PIC X(11) VALUE "00000125.50".
Exercise 7: Case Conversion with INSPECT CONVERTING
Using INSPECT CONVERTING (not intrinsic functions), convert the string "Hello World From COBOL" to all uppercase. Display the result.
Exercise 8: Phone Number Formatting
Given a raw phone number input that may contain parentheses, spaces, and hyphens, extract only the digits and reformat as NNN-NNN-NNNN:
01 WS-RAW-PHONE PIC X(14) VALUE "(312) 555-1234".
Expected output: "312-555-1234"
Use reference modification to iterate through characters and build the clean number.
Tier 2: Intermediate (Exercises 9-16)
These exercises require combining multiple string operations and handling edge cases.
Exercise 9: Pipe-Delimited Record Builder
Write a program that takes the following fields and builds a pipe-delimited output record. Use the STRING statement with a delimiter stored in a variable:
01 WS-EMP-ID PIC X(06) VALUE "E10042".
01 WS-EMP-NAME PIC X(20) VALUE "MARTINEZ, CARLOS".
01 WS-EMP-DEPT PIC X(10) VALUE "FINANCE".
01 WS-EMP-SALARY PIC 9(6)V99 VALUE 72500.00.
Expected output: "E10042|MARTINEZ, CARLOS|FINANCE|72500.00"
Exercise 10: Multi-Delimiter Parsing
Parse the following record that uses both commas and pipes as delimiters. Use UNSTRING with OR and capture the delimiter used for each field with DELIMITER IN:
01 WS-MIXED PIC X(60)
VALUE "ACCT-001|SAVINGS,2500.00|2024-01-15".
Display each field and the delimiter that followed it.
Exercise 11: Word Counter
Write a paragraph that counts the number of words in a string. A word is defined as a sequence of non-space characters separated by one or more spaces:
01 WS-TEXT PIC X(60)
VALUE " THE QUICK BROWN FOX JUMPED ".
Expected output: "Word count: 5"
Hint: Use UNSTRING with DELIMITED BY ALL SPACES and TALLYING IN, or implement a character-by-character loop.
Exercise 12: Search and Replace
Implement a search-and-replace operation that replaces ALL occurrences of "CAT" with "DOG" in the following string:
01 WS-INPUT PIC X(60)
VALUE "THE CAT SAT ON THE MAT WITH THE CAT".
Expected output: "THE DOG SAT ON THE MAT WITH THE DOG"
Since the search and replacement strings are the same length, you may use either INSPECT REPLACING ALL or a loop with reference modification.
Exercise 13: SSN Masking
Write code that masks all but the last 4 digits of a Social Security Number:
01 WS-SSN PIC X(11) VALUE "123-45-6789".
Expected output: "***-**-6789"
Use INSPECT REPLACING CHARACTERS with BEFORE INITIAL to mask the first part.
Exercise 14: Address Line Builder
Build a formatted two-line address from the following components. Handle the case where the unit number might be empty:
01 WS-STREET PIC X(30) VALUE "456 ELM BOULEVARD".
01 WS-UNIT PIC X(10) VALUE "SUITE 200".
01 WS-CITY PIC X(20) VALUE "CHICAGO".
01 WS-STATE PIC X(02) VALUE "IL".
01 WS-ZIP PIC X(10) VALUE "60601-3456".
Expected output:
456 ELM BOULEVARD, SUITE 200
CHICAGO, IL 60601-3456
If WS-UNIT is spaces, the first line should be just the street address without a trailing comma.
Exercise 15: Extract Initials
Write a program that extracts the first letter of each word in a full name and formats them as initials with periods:
01 WS-NAME PIC X(40) VALUE "JOHN MICHAEL ROBERT SMITH".
Expected output: "J.M.R.S."
Exercise 16: Numeric Field Validation
Write a validation routine using INSPECT TALLYING that checks whether a given field contains a valid dollar amount (digits, at most one decimal point, at most one leading negative sign):
01 WS-AMOUNT-1 PIC X(12) VALUE "12345.67".
01 WS-AMOUNT-2 PIC X(12) VALUE "123.45.67".
01 WS-AMOUNT-3 PIC X(12) VALUE "-500.00".
01 WS-AMOUNT-4 PIC X(12) VALUE "12A45.00".
Display whether each amount is valid or invalid and the reason.
Tier 3: Applied (Exercises 17-24)
These exercises involve realistic data processing scenarios combining multiple techniques.
Exercise 17: CSV Record Validator
Write a program that validates CSV records containing employee data. Each record should have exactly 5 comma-separated fields:
EMP-ID,LAST-NAME,FIRST-NAME,DEPARTMENT,SALARY
Validate: - EMP-ID is 6 characters starting with "E" - LAST-NAME and FIRST-NAME are not empty - DEPARTMENT is one of: IT, HR, FINANCE, SALES, OPS - SALARY is a valid numeric value greater than 0
Test with at least 5 records, including 2 that fail validation. Display valid records in a formatted report and list errors for invalid records.
Exercise 18: Email Address Validation
Write a validation routine for email addresses. Check: - Exactly one "@" symbol - At least one "." after the "@" - Non-empty local part (before @) - Non-empty domain part (after @)
Test with these inputs:
user@company.com (valid)
user.name@dept.co.uk (valid)
@company.com (invalid - empty local)
user@ (invalid - empty domain)
user@@company.com (invalid - two @)
user.company.com (invalid - no @)
Exercise 19: Fixed-Format to CSV Converter
Write a program that reads fixed-format records and converts them to CSV format. The input layout is:
Positions 1-5: Account Number (numeric)
Positions 6-25: Customer Name
Positions 26-45: Street Address
Positions 46-60: City
Positions 61-62: State
Positions 63-67: ZIP Code
Create at least 4 sample records in WORKING-STORAGE and produce CSV output. Trim trailing spaces from each field in the CSV output.
Exercise 20: String Compression
Write a routine that removes all extra spaces from a string, leaving only single spaces between words:
01 WS-INPUT PIC X(60)
VALUE " THE QUICK BROWN FOX ".
Expected output: "THE QUICK BROWN FOX"
Exercise 21: Title Case Conversion
Convert a string to Title Case (first letter of each word uppercase, rest lowercase):
01 WS-INPUT PIC X(40) VALUE "the quick brown fox jumps".
Expected output: "The Quick Brown Fox Jumps"
Use a combination of FUNCTION LOWER-CASE, FUNCTION UPPER-CASE, and reference modification.
Exercise 22: Date Validation and Formatting
Write a comprehensive date parser that accepts dates in multiple formats and converts them all to ISO format (YYYY-MM-DD):
MM/DD/YYYY(e.g.,12/25/2024)DD-MON-YYYY(e.g.,25-DEC-2024)YYYYMMDD(e.g.,20241225)
Validate the date components (month 1-12, day 1-31). Display the original format detected and the ISO output.
Exercise 23: Report Header Builder
Create a reusable paragraph that builds a centered report header. Given a title string and a line width (80 characters), center the title and surround it with a border:
================================================================================
QUARTERLY FINANCIAL REPORT
================================================================================
Calculate the padding dynamically based on the logical length of the title.
Exercise 24: Multi-Line Address Parser
Parse a single-line address string into components. The input may be in any of these formats:
"123 MAIN ST, APT 4B, SPRINGFIELD, IL 62701"
"456 OAK AVE, PORTLAND, OR 97201"
"789 PINE RD, SUITE 100, NEW YORK, NY 10001-2345"
Parse into: Street, Unit (optional), City, State, ZIP. Handle the optional unit and optional ZIP+4 extension.
Tier 4: Integration (Exercises 25-32)
These exercises require building more complete programs that integrate string handling with other COBOL features.
Exercise 25: Fixed-Width Report Line Builder
Build a report line generator that places values at specific column positions:
| Column | Width | Field |
|---|---|---|
| 1-20 | 20 | Employee Name |
| 22-31 | 10 | Department |
| 33-48 | 16 | Salary (formatted with $ and commas) |
| 50-59 | 10 | Hire Date (MM/DD/YYYY) |
Generate a header row and at least 5 data rows. Use STRING with WITH POINTER for column alignment.
Exercise 26: Data Cleansing Pipeline
Write a program that processes "dirty" input records through a series of cleansing steps:
- Convert to uppercase
- Replace all tab characters (if any) with spaces
- Compress multiple spaces to single spaces
- Trim leading and trailing spaces
- Validate that required fields are not empty
- Standardize date formats to YYYY-MM-DD
Process at least 5 sample records and display before/after results.
Exercise 27: Name Formatter
Write a program that accepts names in various formats and standardizes them all to "LASTNAME, FIRSTNAME M." format:
- "John Q. Smith" -> "SMITH, JOHN Q."
- "SMITH, JOHN" -> "SMITH, JOHN"
- "mary jane watson" -> "WATSON, MARY J."
- "DR. JAMES WILSON" -> "WILSON, JAMES (DR.)"
Handle at least 6 different name format variations.
Exercise 28: Simple Template Engine
Create a template expansion system. Given a template string with placeholders marked by {FIELD-NAME}, replace each placeholder with actual values:
Template: "Dear {FIRST-NAME}, your account {ACCT-NUM} has
a balance of {BALANCE}."
Process the template for at least 3 different sets of values.
Exercise 29: Log Message Parser
Parse log messages in the following format and extract components:
2024-03-15 14:30:45 [ERROR] Module: ACCTPROC - Invalid account number: 99999
2024-03-15 14:30:46 [INFO] Module: BATCHCTL - Batch 42 started
2024-03-15 14:31:02 [WARN] Module: ACCTPROC - Balance below threshold: $50.00
Extract: Date, Time, Severity, Module, Message. Count the number of each severity level.
Exercise 30: Check Digit Calculator
Implement the Luhn algorithm for validating credit card numbers. Given a card number as a string:
- Parse the digits from the string (removing any spaces or hyphens)
- Apply the Luhn algorithm
- Display whether the number is valid
Test with:
- "4539 1488 0343 6467" (valid)
- "1234 5678 9012 3456" (invalid)
Exercise 31: Encoded Record Processor
Write a program that processes records where certain fields are encoded. The encoding scheme is:
- Letters are shifted by 3 positions (A->D, B->E, ..., X->A, Y->B, Z->C)
- Digits remain unchanged
- Special characters remain unchanged
Decode 3 sample records and display the original and decoded versions.
Exercise 32: Report Formatter with Word Wrap
Write a paragraph that takes a long text string and formats it into multiple lines of a specified maximum width (e.g., 40 characters) without breaking words:
01 WS-LONG-TEXT PIC X(200) VALUE
"THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG "
& "AND THEN RAN ALL THE WAY HOME TO REST".
Display the text wrapped at 40 characters per line. Break only at spaces.
Tier 5: Challenge (Exercises 33-38)
These are advanced exercises that require creative problem-solving and deep understanding of COBOL string handling.
Exercise 33: CSV Parser with Quoted Fields
Implement a CSV parser that correctly handles quoted fields. In standard CSV, fields may be enclosed in double quotes, allowing commas within a field:
"Smith, John",ACCT-001,"1,500.00",2024-03-15
This should parse as 4 fields:
1. Smith, John
2. ACCT-001
3. 1,500.00
4. 2024-03-15
Handle escaped quotes within quoted fields ("" represents a literal ").
Exercise 34: Soundex Algorithm
Implement the Soundex algorithm, which converts a name to a phonetic code. The algorithm:
- Keep the first letter
- Replace consonants with digits (B,F,P,V=1; C,G,J,K,Q,S,X,Z=2; D,T=3; L=4; M,N=5; R=6)
- Remove adjacent duplicate digits
- Remove vowels (A, E, I, O, U, H, W, Y)
- Pad or truncate to exactly 4 characters
Test with: SMITH (S530), JOHNSON (J525), WILLIAMS (W452).
Exercise 35: Data Migration Converter
Write a complete data migration program that:
- Reads 10 legacy fixed-format customer records
- Parses name (handling "LAST, FIRST" and "FIRST LAST" formats)
- Standardizes address components
- Validates all fields
- Produces a new fixed-format record with a different layout
- Generates a migration report with record counts, error counts, and a list of records that failed validation
Exercise 36: Expression Tokenizer
Write a simple tokenizer that breaks a mathematical expression string into tokens:
"(125 + 37) * 42 / 7 - 3"
Identify each token as: NUMBER, OPERATOR (+, -, *, /), or PARENTHESIS. Display the token list.
Exercise 37: Multi-Record Address Standardizer
Write a program that standardizes address abbreviations using a translation table:
| Abbreviation | Standard |
|---|---|
| ST | STREET |
| AVE | AVENUE |
| BLVD | BOULEVARD |
| DR | DRIVE |
| LN | LANE |
| CT | COURT |
| RD | ROAD |
| APT | APARTMENT |
| STE | SUITE |
Process 6 addresses, expanding abbreviations to their full forms. Handle abbreviations that appear at the end of a word or followed by a period.
Exercise 38: COBOL String Library
Create a COBOL program that implements a reusable set of string utility paragraphs:
LEFT-PAD-- Pad a string on the left with a specified character to a specified lengthRIGHT-PAD-- Pad a string on the rightCENTER-- Center a string within a specified widthCONTAINS-- Check if a string contains a substring (return position or 0)STARTS-WITH-- Check if a string starts with a given prefixENDS-WITH-- Check if a string ends with a given suffixREPLACE-ALL-- Replace all occurrences of a substring (handles different-length replacements)SPLIT-COUNT-- Count the number of delimited fields in a string
Write test cases for each utility paragraph demonstrating both normal and edge cases.
Solution Notes
Selected solutions for exercises 1, 3, 5, 8, 12, 15, 18, 21, and 25 are provided in code/exercise-solutions.cob. These solutions demonstrate proper COBOL coding style, error handling, and documentation.
For exercises not included in the solutions file, consider these approaches: - Start by identifying which string operation (STRING, UNSTRING, INSPECT, reference modification) is most appropriate - Initialize all receiving fields and counters before use - Always code ON OVERFLOW handlers - Test with boundary cases: empty fields, maximum-length data, and special characters