Chapter 9 Quiz: String Handling and Character Manipulation
Test your understanding of COBOL string handling with these 28 questions. Try to answer each question before revealing the answer.
Question 1
What is the key difference between DELIMITED BY SIZE and DELIMITED BY SPACE in a STRING statement?
Show Answer
`DELIMITED BY SIZE` transfers the entire contents of the source field, including all trailing spaces (the full PIC-defined length). `DELIMITED BY SPACE` stops transferring characters when the first space character is encountered. For a field `PIC X(20) VALUE "JOHN"`, `DELIMITED BY SIZE` transfers all 20 characters (JOHN + 16 spaces), while `DELIMITED BY SPACE` transfers only 4 characters (JOHN).Question 2
What must you do before executing a STRING statement with a WITH POINTER clause?
Show Answer
You must initialize the pointer variable to the desired starting position (typically 1). If the pointer is not initialized or contains a value less than 1 or greater than the length of the receiving field plus 1, the `STRING` statement triggers the `ON OVERFLOW` condition without transferring any data.Question 3
In the following code, what will WS-PTR contain after the STRING executes?
01 WS-OUTPUT PIC X(20) VALUE SPACES.
01 WS-PTR PIC 99 VALUE 1.
MOVE 1 TO WS-PTR
STRING "HELLO" DELIMITED BY SIZE
INTO WS-OUTPUT
WITH POINTER WS-PTR
END-STRING
Show Answer
`WS-PTR` will contain 6. The pointer advances past the last character written. "HELLO" is 5 characters, so the pointer moves from 1 to 6 (the next available position). To get the number of characters written, subtract 1 from the pointer value.Question 4
When does the ON OVERFLOW condition trigger for a STRING statement?
Show Answer
The `ON OVERFLOW` condition triggers when: 1. There is not enough room in the receiving field to hold all the data being concatenated (the pointer would exceed the length of the receiving field) 2. The pointer value is less than 1 before execution begins 3. The pointer value exceeds the length of the receiving field plus 1 before execution beginsQuestion 5
When does the ON OVERFLOW condition trigger for an UNSTRING statement?
Show Answer
For `UNSTRING`, the `ON OVERFLOW` condition triggers when: 1. The source field contains more delimited fields than there are receiving fields specified in the `INTO` clause 2. The `WITH POINTER` value is less than 1 before execution begins 3. The `WITH POINTER` value exceeds the length of the source field before execution beginsQuestion 6
What is the difference between DELIMITED BY " " and DELIMITED BY ALL " " in an UNSTRING statement?
Show Answer
`DELIMITED BY " "` (without `ALL`) treats each individual space as a separate delimiter. If there are three consecutive spaces between two words, the first space acts as a delimiter, and the second and third spaces create two empty fields. `DELIMITED BY ALL " "` treats any number of consecutive spaces as a single delimiter, producing no empty fields between words. `ALL` is essential when parsing space-separated data with variable spacing.Question 7
What does the DELIMITER IN clause do in an UNSTRING statement?
Show Answer
The `DELIMITER IN` clause stores the actual delimiter character (or string) that was found when parsing each field. This is useful when using the `OR` keyword with multiple delimiters, as it tells you which delimiter was used to separate each pair of fields. For example, with `DELIMITED BY "|" OR ","`, the `DELIMITER IN` field will contain either `"|"` or `","` depending on which one was found.Question 8
What does the COUNT IN clause do in an UNSTRING statement?
Show Answer
The `COUNT IN` clause stores the number of characters that were actually placed into each receiving field. This is the length of the parsed data, not the defined size of the receiving field. For example, if parsing "AB,CDEF" with `COUNT IN`, the count for the first field would be 2 and the count for the second field would be 4.Question 9
Why must you initialize the TALLYING IN counter to zero before an UNSTRING statement?
Show Answer
The `TALLYING IN` clause increments (adds to) the counter variable rather than replacing its value. If the counter is not initialized to zero, the field count from the current `UNSTRING` will be added to whatever value was already in the counter, producing an incorrect result. The same principle applies to `INSPECT TALLYING` counters.Question 10
What are the three forms of the INSPECT statement?
Show Answer
The three forms are: 1. **INSPECT TALLYING** -- Counts occurrences of characters or strings 2. **INSPECT REPLACING** -- Substitutes characters or strings in place 3. **INSPECT CONVERTING** -- Translates characters using a mapping table (similar to Unix `tr`) Some implementations also support a combined TALLYING-REPLACING form in a single statement.Question 11
What is the difference between INSPECT TALLYING FOR ALL "X", INSPECT TALLYING FOR LEADING "X", and INSPECT TALLYING FOR CHARACTERS?
Show Answer
- `FOR ALL "X"` -- Counts every occurrence of "X" anywhere in the field - `FOR LEADING "X"` -- Counts only consecutive occurrences of "X" at the beginning of the field (or the beginning of the bounded range if AFTER INITIAL is used). Counting stops at the first non-"X" character - `FOR CHARACTERS` -- Counts all characters in the field regardless of their value. This gives the total number of characters (effectively the field size, or the size of the bounded range)Question 12
In INSPECT REPLACING, what is the rule about the lengths of the source and target strings?
Show Answer
In `INSPECT REPLACING ALL literal-1 BY literal-2`, both literals must be exactly the same length. For example, `REPLACING ALL "AB" BY "XY"` is valid (both 2 bytes), but `REPLACING ALL "AB" BY "X"` is invalid (2 bytes vs. 1 byte). This is because `INSPECT REPLACING` operates in-place and cannot change the field's size.Question 13
How does INSPECT CONVERTING work, and what constraint applies to the two string arguments?
Show Answer
`INSPECT CONVERTING` performs character-by-character translation. Each character in the field is compared to the characters in the first string; if a match is found, it is replaced by the character at the corresponding position in the second string. The two strings must be the same length, and each character in the first string maps positionally to the character in the second string. For example, `CONVERTING "ABC" TO "XYZ"` replaces every A with X, every B with Y, and every C with Z.Question 14
What is the effect of BEFORE INITIAL and AFTER INITIAL in an INSPECT statement?
Show Answer
These phrases limit the scope of the `INSPECT` operation: - `BEFORE INITIAL literal` -- The operation applies only to characters before the first occurrence of the specified literal - `AFTER INITIAL literal` -- The operation applies only to characters after the first occurrence of the specified literal If the literal is not found in the field: `BEFORE INITIAL` includes the entire field (everything is "before" a non-existent marker), and `AFTER INITIAL` excludes the entire field (nothing is "after" a non-existent marker).Question 15
What is reference modification, and what is its syntax?
Show Answer
Reference modification is COBOL's mechanism for accessing a substring of a data item by specifying a starting position and optional length. The syntax is: `identifier(start-position:length)` Both values are 1-based (the first character is position 1). The length is optional; if omitted, the substring extends from the start position to the end of the field. Both start-position and length can be literals, data items, or arithmetic expressions. Example: `WS-FIELD(5:3)` extracts 3 characters starting at position 5.Question 16
What happens if you use reference modification with a start position of 0 or a position that exceeds the field length?
Show Answer
This results in undefined behavior. COBOL reference modification does not automatically perform boundary checking. A start position of 0 is invalid because COBOL uses 1-based positions. A start position or start+length-1 that exceeds the field's defined size accesses memory outside the field, which may cause a runtime error, return garbage data, or corrupt adjacent memory. Always validate positions before using reference modification with variable values.Question 17
Can reference modification be used on the receiving side of a MOVE statement?
Show Answer
Yes. Reference modification can be used as a receiving field, which modifies a portion of the data item in place while leaving the rest unchanged. For example:MOVE "XXXX" TO WS-RECORD(5:4)
This replaces positions 5 through 8 of `WS-RECORD` with "XXXX" without affecting any other positions.
Question 18
What is the difference between FUNCTION LENGTH(identifier) and LENGTH OF identifier?
Show Answer
For alphanumeric fields, both return the defined size of the field in bytes. The differences are: - `FUNCTION LENGTH` is a runtime function and can be used with literals: `FUNCTION LENGTH("HELLO")` returns 5 - `LENGTH OF` is a compile-time special register and can only be used with data items - For national (Unicode) fields, `FUNCTION LENGTH` returns the number of characters, while `LENGTH OF` returns the number of bytes Neither returns the "logical" length (i.e., length excluding trailing spaces). To get that, you need to count trailing spaces and subtract them.Question 19
How can you determine the logical length (excluding trailing spaces) of an alphanumeric field?
Show Answer
Use `FUNCTION REVERSE` combined with `INSPECT TALLYING FOR LEADING SPACES`:MOVE 0 TO WS-TRAILING-SPACES
INSPECT FUNCTION REVERSE(WS-FIELD)
TALLYING WS-TRAILING-SPACES
FOR LEADING SPACES
COMPUTE WS-LOGICAL-LENGTH =
FUNCTION LENGTH(WS-FIELD) - WS-TRAILING-SPACES
Alternatively, if `FUNCTION TRIM` is available, you can use:
MOVE FUNCTION LENGTH(FUNCTION TRIM(WS-FIELD))
TO WS-LOGICAL-LENGTH
Question 20
What are the three modes of FUNCTION TRIM?
Show Answer
1. `FUNCTION TRIM(field)` -- Removes both leading and trailing spaces (default) 2. `FUNCTION TRIM(field LEADING)` -- Removes only leading spaces 3. `FUNCTION TRIM(field TRAILING)` -- Removes only trailing spaces Note: `FUNCTION TRIM` was introduced in COBOL 2002 and may not be available on older compilers.Question 21
What does FUNCTION ORD("A") return in an ASCII environment, and why?
Show Answer
In an ASCII environment, `FUNCTION ORD("A")` returns 66. This is because `FUNCTION ORD` returns a 1-based ordinal position in the collating sequence, not the raw character code. The ASCII code for "A" is 65, and adding 1 (for the 1-based ordinal) gives 66. Similarly, `FUNCTION ORD(" ")` returns 33 (ASCII code 32 + 1).Question 22
How do EBCDIC and ASCII collating sequences differ, and why does it matter for COBOL programs?
Show Answer
In ASCII, the order is: special characters, digits (0-9), uppercase letters (A-Z), lowercase letters (a-z). In EBCDIC, the order is: special characters, lowercase letters (a-z), uppercase letters (A-Z), digits (0-9). This means: - In ASCII, `"9" < "A"` is true - In EBCDIC, `"9" > "A"` is true This affects sorting, comparisons, and any code that uses ordinal values for character classification. Programs migrated between EBCDIC and ASCII platforms may produce different sorting results for mixed alphanumeric data.Question 23
What is the output of the following code?
01 WS-TEXT PIC X(20) VALUE "HELLO WORLD".
INSPECT WS-TEXT
REPLACING ALL "L" BY "R"
DISPLAY WS-TEXT
Show Answer
The output is `"HERRO WORRD"`. `INSPECT REPLACING ALL` replaces every occurrence of "L" with "R" throughout the entire field. Both "L" characters in "HELLO" and the "L" in "WORLD" are replaced.Question 24
What is the output of the following code?
01 WS-DATA PIC X(15) VALUE "AABBBCCDDDEEE".
01 WS-COUNT PIC 999 VALUE 0.
INSPECT WS-DATA
TALLYING WS-COUNT
FOR LEADING "A"
DISPLAY WS-COUNT
Show Answer
The output is `002`. `TALLYING FOR LEADING "A"` counts consecutive "A" characters at the beginning of the field. The first two characters are "A", and the third is "B", so counting stops. The result is 2.Question 25
What happens when you execute STRING ... INTO WS-FIELD without first initializing WS-FIELD to spaces?
Show Answer
The `STRING` statement writes new data starting at the pointer position (or position 1 if no pointer is specified) but does NOT clear the rest of the receiving field. Any characters beyond the last character written by the `STRING` retain their previous values. This can result in leftover data from a previous operation appearing after the new data, producing incorrect output. Always initialize the receiving field with `MOVE SPACES TO WS-FIELD` before the `STRING`.Question 26
Given the following code, how many fields are placed in WS-TALLY?
01 WS-INPUT PIC X(30) VALUE "A,,B,C,,D".
01 WS-F1 PIC X(05).
01 WS-F2 PIC X(05).
01 WS-F3 PIC X(05).
01 WS-F4 PIC X(05).
01 WS-F5 PIC X(05).
01 WS-F6 PIC X(05).
01 WS-TALLY PIC 99 VALUE 0.
MOVE 0 TO WS-TALLY
UNSTRING WS-INPUT
DELIMITED BY ","
INTO WS-F1 WS-F2 WS-F3 WS-F4 WS-F5 WS-F6
TALLYING IN WS-TALLY
END-UNSTRING
Show Answer
`WS-TALLY` will contain 6. The input `"A,,B,C,,D"` has six comma-delimited fields: "A", "" (empty), "B", "C", "" (empty), and "D". Without `DELIMITED BY ALL`, each comma is a separate delimiter, so consecutive commas produce empty fields. The empty fields (WS-F2 and WS-F5) will contain spaces (the default for an empty delimited field).Question 27
Write a single INSPECT statement that converts all lowercase letters to uppercase in a field called WS-TEXT.
Show Answer
INSPECT WS-TEXT
CONVERTING
"abcdefghijklmnopqrstuvwxyz"
TO
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Alternatively, you can use `MOVE FUNCTION UPPER-CASE(WS-TEXT) TO WS-TEXT`, but the question specifically asks for an `INSPECT` statement.
Question 28
You have a field WS-SSN PIC X(11) VALUE "123-45-6789". Write code using INSPECT to mask it as "***-**-6789" (mask all characters before the last segment).
Show Answer
INSPECT WS-SSN
REPLACING CHARACTERS BY "*"
BEFORE INITIAL "6789"
This replaces every character before the first occurrence of "6789" with an asterisk. Since "6789" starts at position 8, positions 1 through 7 ("123-45-") become "***-**-" -- wait, that is not quite right. The hyphens would also be replaced. The actual result would be `"*******6789"`.
To preserve the hyphens, use a two-step approach:
INSPECT WS-SSN
REPLACING ALL "1" BY "*"
ALL "2" BY "*"
ALL "3" BY "*"
ALL "4" BY "*"
ALL "5" BY "*"
BEFORE INITIAL "6789"
Or more elegantly, use reference modification:
MOVE "***-**-" TO WS-SSN(1:7)
Scoring Guide
| Score | Level |
|---|---|
| 25-28 | Expert -- You have mastered COBOL string handling |
| 20-24 | Proficient -- Strong understanding with minor gaps |
| 15-19 | Competent -- Solid foundation, review the areas you missed |
| 10-14 | Developing -- Re-read sections 9.1-9.5 and practice the exercises |
| Below 10 | Beginning -- Work through the chapter examples before retaking |