MODULE 7 · WORKING WITH TEXT · 4/8

Splitting text with UNSTRING

15 min30 XPExercise

UNSTRING is the opposite of STRING: it splits one field into several receiving fields at each delimiter.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. UNSDEMO.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-REC       PIC X(40) VALUE "C00042;GRACE HOPPER;ARLINGTON".
       01  WS-ID        PIC X(6).
       01  WS-NAME      PIC X(20).
       01  WS-CITY      PIC X(15).
       01  WS-NAME-LEN  PIC 9(2).
       01  WS-FIELDS    PIC 9(2).
       PROCEDURE DIVISION.
           MOVE 0 TO WS-FIELDS
           UNSTRING WS-REC DELIMITED BY ";"
               INTO WS-ID
                    WS-NAME COUNT IN WS-NAME-LEN
                    WS-CITY
               TALLYING IN WS-FIELDS
           END-UNSTRING
           DISPLAY "ID:     [" WS-ID "]"
           DISPLAY "NAME:   [" WS-NAME "] " WS-NAME-LEN " CHARS"
           DISPLAY "CITY:   [" WS-CITY "]"
           DISPLAY "FIELDS: " WS-FIELDS
           STOP RUN.

Output:

ID:     [C00042]
NAME:   [GRACE HOPPER        ] 12 CHARS
CITY:   [ARLINGTON      ]
FIELDS: 03

Each piece is moved into the next INTO field using normal MOVE rules: padded with spaces, or truncated if it is too long.

The optional phrases:

Phrase Meaning
COUNT IN n after a receiver: how many characters that piece had, before padding or truncation
DELIMITER IN d after a receiver: which delimiter ended that piece
TALLYING IN n once, at the end: adds the number of receivers filled to n
WITH POINTER p start scanning at position p; updated as it goes
ON OVERFLOW runs if there was text left over when the receivers ran out

Because TALLYING adds to the counter, set it to zero first, just as the example does with MOVE 0 TO WS-FIELDS.

Choosing delimiters

       IDENTIFICATION DIVISION.
       PROGRAM-ID. UNSALL.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-A         PIC X(8).
       01  WS-B         PIC X(8).
       01  WS-C         PIC X(8).
       01  WS-DAY       PIC 9(2).
       01  WS-MONTH     PIC 9(2).
       01  WS-YEAR      PIC 9(4).
       PROCEDURE DIVISION.
           UNSTRING "RED   GREEN BLUE" DELIMITED BY ALL SPACE
               INTO WS-A WS-B WS-C
           END-UNSTRING
           DISPLAY "[" WS-A "][" WS-B "][" WS-C "]"
           UNSTRING "7-3/2026" DELIMITED BY "/" OR "-"
               INTO WS-DAY WS-MONTH WS-YEAR
           END-UNSTRING
           DISPLAY WS-YEAR WS-MONTH WS-DAY
           MOVE "OLD" TO WS-C
           UNSTRING "ONE,TWO" DELIMITED BY ","
               INTO WS-A WS-B WS-C
           END-UNSTRING
           DISPLAY "[" WS-A "][" WS-B "][" WS-C "]"
           UNSTRING "A,B,C,D" DELIMITED BY ","
               INTO WS-A WS-B WS-C
               ON OVERFLOW DISPLAY "MORE FIELDS THAN RECEIVERS"
           END-UNSTRING
           STOP RUN.

Output:

[RED     ][GREEN   ][BLUE    ]
20260307
[ONE     ][TWO     ][OLD     ]
MORE FIELDS THAN RECEIVERS
  • DELIMITED BY ALL SPACE treats a run of spaces as one delimiter. Without ALL, two spaces in a row would produce an empty field between them.
  • OR lets several delimiters split the same text: here - and /.
  • A numeric receiver gets the piece as if it were moved from an alphanumeric field, so "7" into PIC 9(2) becomes 07. That is a handy way to turn 7-3/2026 into a proper date.
  • Receivers that get no data are not changed. WS-C still says OLD after splitting ONE,TWO. Clear your receivers first, or check the tally.

Leading delimiters

If the text starts with a delimiter, the first receiver gets an empty piece, even with ALL. " RED GREEN" delimited by ALL SPACE puts spaces in the first receiver and RED in the second. Trim the input first (next lessons), or start with a pointer past the blanks.

On the job

UNSTRING is the workhorse for incoming delimited data: CSV extracts, pipe-separated partner feeds, key=value parameter cards read at the start of a batch job. The tally and ON OVERFLOW are your first line of defence against a malformed record.

Your task

Dates keyed in by branch staff arrive as day, month and year separated by / or -, with or without leading zeros: 4/9/2026, 24-12-2026, 1/1-2027. Convert each to ISO format YYYY-MM-DD.

Read lines until one says END. For each date, display either the ISO date or, if it does not split into exactly three parts, the word INVALID and the original text:

2026-09-04
2026-12-24
INVALID: 12/2026

You can assume each part that is present is numeric.

fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.