MainframeMaster

COBOL Tutorial

COBOL CHARACTER and CHARACTERS

The CHARACTER and CHARACTERS clauses in COBOL provide powerful string manipulation capabilities for character-level processing and text handling operations. These clauses enable sophisticated string examination, pattern matching, character replacement, and text transformation processes essential for data validation, text processing, report formatting, and data cleansing operations in enterprise applications where precise character-level control and string manipulation are critical for business logic implementation and data integrity maintenance across various text processing scenarios.

Understanding CHARACTER Operations

CHARACTER and CHARACTERS clauses work with string manipulation statements like INSPECT to provide character-level processing capabilities. These clauses enable detailed examination, counting, replacing, and converting of individual characters or character groups within strings, offering precise control over text processing operations essential for data validation, formatting, and transformation tasks.

Key Features:

  • Character-level string examination with precise positioning and pattern matching
  • Text pattern matching and replacement with flexible search criteria and conditions
  • Character counting and frequency analysis for statistical text processing
  • Case conversion and character transformation for data normalization
  • Character validation and filtering for data quality assurance
  • String parsing and tokenization for complex text analysis and extraction
  • Integration with INSPECT statement for comprehensive string manipulation workflows
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
*> Basic CHARACTER operations with INSPECT statement DATA DIVISION. WORKING-STORAGE SECTION. 01 STRING-PROCESSING-DATA. 05 INPUT-STRING PIC X(100) VALUE "The Quick Brown Fox Jumps Over The Lazy Dog". 05 SEARCH-CHARACTER PIC X VALUE "o". 05 REPLACE-CHARACTER PIC X VALUE "0". 05 CHARACTER-COUNT PIC 9(3) VALUE ZERO. 01 PROCESSING-RESULTS. 05 ORIGINAL-STRING PIC X(100). 05 MODIFIED-STRING PIC X(100). 05 BEFORE-COUNT PIC 9(3) VALUE ZERO. 05 AFTER-COUNT PIC 9(3) VALUE ZERO. 01 CHARACTER-ANALYSIS. 05 VOWEL-COUNT PIC 9(3) VALUE ZERO. 05 CONSONANT-COUNT PIC 9(3) VALUE ZERO. 05 SPACE-COUNT PIC 9(3) VALUE ZERO. 05 UPPER-CASE-COUNT PIC 9(3) VALUE ZERO. 05 LOWER-CASE-COUNT PIC 9(3) VALUE ZERO. PROCEDURE DIVISION. BASIC-CHARACTER-OPERATIONS. PERFORM INITIALIZE-PROCESSING PERFORM COUNT-SPECIFIC-CHARACTER PERFORM REPLACE-CHARACTERS PERFORM ANALYZE-CHARACTER-TYPES PERFORM DISPLAY-RESULTS. INITIALIZE-PROCESSING. MOVE INPUT-STRING TO ORIGINAL-STRING MOVE INPUT-STRING TO MODIFIED-STRING MOVE ZERO TO CHARACTER-COUNT VOWEL-COUNT CONSONANT-COUNT SPACE-COUNT UPPER-CASE-COUNT LOWER-CASE-COUNT. COUNT-SPECIFIC-CHARACTER. *> Count occurrences of specific character INSPECT INPUT-STRING TALLYING CHARACTER-COUNT FOR ALL CHARACTERS SEARCH-CHARACTER MOVE CHARACTER-COUNT TO BEFORE-COUNT DISPLAY "Character '" SEARCH-CHARACTER "' appears " CHARACTER-COUNT " times". REPLACE-CHARACTERS. *> Replace all occurrences of search character INSPECT MODIFIED-STRING REPLACING ALL CHARACTERS SEARCH-CHARACTER BY REPLACE-CHARACTER *> Count the replacement character to verify MOVE ZERO TO CHARACTER-COUNT INSPECT MODIFIED-STRING TALLYING CHARACTER-COUNT FOR ALL CHARACTERS REPLACE-CHARACTER MOVE CHARACTER-COUNT TO AFTER-COUNT DISPLAY "After replacement, character '" REPLACE-CHARACTER "' appears " CHARACTER-COUNT " times". ANALYZE-CHARACTER-TYPES. *> Count different types of characters INSPECT INPUT-STRING TALLYING VOWEL-COUNT FOR ALL CHARACTERS "a" "e" "i" "o" "u" "A" "E" "I" "O" "U" INSPECT INPUT-STRING TALLYING SPACE-COUNT FOR ALL CHARACTERS " " INSPECT INPUT-STRING TALLYING UPPER-CASE-COUNT FOR ALL CHARACTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" INSPECT INPUT-STRING TALLYING LOWER-CASE-COUNT FOR ALL CHARACTERS "abcdefghijklmnopqrstuvwxyz" COMPUTE CONSONANT-COUNT = UPPER-CASE-COUNT + LOWER-CASE-COUNT - VOWEL-COUNT. DISPLAY-RESULTS. DISPLAY "=== Character Analysis Results ===" DISPLAY "Original: " ORIGINAL-STRING DISPLAY "Modified: " MODIFIED-STRING DISPLAY "Vowels: " VOWEL-COUNT DISPLAY "Consonants: " CONSONANT-COUNT DISPLAY "Spaces: " SPACE-COUNT DISPLAY "Uppercase: " UPPER-CASE-COUNT DISPLAY "Lowercase: " LOWER-CASE-COUNT.

Advanced String Manipulation Techniques

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
*> Advanced character processing for complex string operations DATA DIVISION. WORKING-STORAGE SECTION. 01 ADVANCED-STRING-CONTROL. 05 SOURCE-TEXT PIC X(200) VALUE "Product#123 costs $45.99 (discount 15%) - Call 555-0123". 05 WORK-STRING PIC X(200). 05 PATTERN-STRING PIC X(50). 05 REPLACEMENT-STRING PIC X(50). 01 CHARACTER-CLASSIFICATION. 05 DIGIT-COUNT PIC 9(3) VALUE ZERO. 05 ALPHA-COUNT PIC 9(3) VALUE ZERO. 05 SPECIAL-COUNT PIC 9(3) VALUE ZERO. 05 PUNCTUATION-COUNT PIC 9(3) VALUE ZERO. 01 VALIDATION-PATTERNS. 05 PHONE-PATTERN PIC X(20) VALUE "999-9999". 05 PRICE-PATTERN PIC X(20) VALUE "$99.99". 05 DISCOUNT-PATTERN PIC X(20) VALUE "99%". 01 EXTRACTION-RESULTS. 05 EXTRACTED-PHONE PIC X(12). 05 EXTRACTED-PRICE PIC X(10). 05 EXTRACTED-DISCOUNT PIC X(5). 05 PRODUCT-NUMBER PIC X(10). 01 TRANSFORMATION-CONTROL. 05 NORMALIZE-FLAG PIC X VALUE 'N'. 88 NORMALIZE-TEXT VALUE 'Y'. 05 CASE-CONVERT-FLAG PIC X VALUE 'U'. 88 CONVERT-UPPER VALUE 'U'. 88 CONVERT-LOWER VALUE 'L'. 88 CONVERT-MIXED VALUE 'M'. PROCEDURE DIVISION. ADVANCED-STRING-MANIPULATION. PERFORM INITIALIZE-ADVANCED-PROCESSING PERFORM CLASSIFY-CHARACTERS PERFORM EXTRACT-PATTERNS PERFORM NORMALIZE-STRING-FORMAT PERFORM VALIDATE-EXTRACTED-DATA PERFORM DISPLAY-ADVANCED-RESULTS. INITIALIZE-ADVANCED-PROCESSING. MOVE SOURCE-TEXT TO WORK-STRING MOVE ZERO TO DIGIT-COUNT ALPHA-COUNT SPECIAL-COUNT PUNCTUATION-COUNT MOVE SPACES TO EXTRACTED-PHONE EXTRACTED-PRICE EXTRACTED-DISCOUNT PRODUCT-NUMBER. CLASSIFY-CHARACTERS. *> Count digits INSPECT SOURCE-TEXT TALLYING DIGIT-COUNT FOR ALL CHARACTERS "0123456789" *> Count alphabetic characters INSPECT SOURCE-TEXT TALLYING ALPHA-COUNT FOR ALL CHARACTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" *> Count punctuation INSPECT SOURCE-TEXT TALLYING PUNCTUATION-COUNT FOR ALL CHARACTERS ".,;:!?()[]{}"'" *> Count special characters INSPECT SOURCE-TEXT TALLYING SPECIAL-COUNT FOR ALL CHARACTERS "@#$%^&*+-=<>/\|~" DISPLAY "=== Character Classification ===" DISPLAY "Digits: " DIGIT-COUNT DISPLAY "Letters: " ALPHA-COUNT DISPLAY "Punctuation: " PUNCTUATION-COUNT DISPLAY "Special: " SPECIAL-COUNT. EXTRACT-PATTERNS. *> Extract phone number pattern PERFORM EXTRACT-PHONE-NUMBER *> Extract price pattern PERFORM EXTRACT-PRICE-INFO *> Extract discount percentage PERFORM EXTRACT-DISCOUNT-INFO *> Extract product number PERFORM EXTRACT-PRODUCT-NUMBER. EXTRACT-PHONE-NUMBER. *> Look for phone pattern XXX-XXXX MOVE SPACES TO EXTRACTED-PHONE *> Simplified extraction - in real implementation, *> use more sophisticated pattern matching IF SOURCE-TEXT(39:8) = "555-0123" MOVE "555-0123" TO EXTRACTED-PHONE DISPLAY "Phone extracted: " EXTRACTED-PHONE END-IF. EXTRACT-PRICE-INFO. *> Extract price pattern $XX.XX MOVE SPACES TO EXTRACTED-PRICE *> Look for dollar sign followed by digits UNSTRING SOURCE-TEXT DELIMITED BY " " "(" ")" INTO WS-WORD-1 WS-WORD-2 WS-WORD-3 WS-WORD-4 WS-WORD-5 WS-WORD-6 WS-WORD-7 WS-WORD-8 END-UNSTRING *> Check each word for price pattern PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 8 EVALUATE WS-I WHEN 1 IF WS-WORD-1(1:1) = "$" MOVE WS-WORD-1 TO EXTRACTED-PRICE END-IF WHEN 2 IF WS-WORD-2(1:1) = "$" MOVE WS-WORD-2 TO EXTRACTED-PRICE END-IF *> Continue for other positions... END-EVALUATE END-PERFORM IF EXTRACTED-PRICE NOT = SPACES DISPLAY "Price extracted: " EXTRACTED-PRICE END-IF. EXTRACT-DISCOUNT-INFO. *> Extract discount percentage MOVE SPACES TO EXTRACTED-DISCOUNT *> Look for number followed by % PERFORM VARYING WS-POS FROM 1 BY 1 UNTIL WS-POS > LENGTH OF SOURCE-TEXT - 2 IF SOURCE-TEXT(WS-POS:1) IS NUMERIC AND SOURCE-TEXT(WS-POS + 1:1) IS NUMERIC AND SOURCE-TEXT(WS-POS + 2:1) = "%" STRING SOURCE-TEXT(WS-POS:2) "%" DELIMITED BY SIZE INTO EXTRACTED-DISCOUNT END-STRING EXIT PERFORM END-IF END-PERFORM IF EXTRACTED-DISCOUNT NOT = SPACES DISPLAY "Discount extracted: " EXTRACTED-DISCOUNT END-IF. EXTRACT-PRODUCT-NUMBER. *> Extract product number after "Product#" MOVE SPACES TO PRODUCT-NUMBER UNSTRING SOURCE-TEXT DELIMITED BY "#" " " INTO WS-TEMP-1 PRODUCT-NUMBER END-UNSTRING IF PRODUCT-NUMBER NOT = SPACES DISPLAY "Product Number: " PRODUCT-NUMBER END-IF. NORMALIZE-STRING-FORMAT. MOVE 'Y' TO NORMALIZE-FLAG MOVE 'U' TO CASE-CONVERT-FLAG IF NORMALIZE-TEXT PERFORM CLEAN-EXTRA-SPACES PERFORM STANDARDIZE-PUNCTUATION IF CONVERT-UPPER PERFORM CONVERT-TO-UPPERCASE ELSE IF CONVERT-LOWER PERFORM CONVERT-TO-LOWERCASE END-IF END-IF. CLEAN-EXTRA-SPACES. *> Replace multiple spaces with single space PERFORM UNTIL WS-NO-MORE-CHANGES MOVE 'N' TO WS-CHANGES-MADE INSPECT WORK-STRING REPLACING ALL " " BY " " *> Check if any changes were made IF WORK-STRING NOT = WS-PREVIOUS-STRING MOVE 'Y' TO WS-CHANGES-MADE MOVE WORK-STRING TO WS-PREVIOUS-STRING ELSE MOVE 'Y' TO WS-NO-MORE-CHANGES END-IF END-PERFORM. STANDARDIZE-PUNCTUATION. *> Ensure space after punctuation INSPECT WORK-STRING REPLACING ALL ".(" BY ". (" INSPECT WORK-STRING REPLACING ALL ".)" BY ". )" INSPECT WORK-STRING REPLACING ALL "-" BY " - ". CONVERT-TO-UPPERCASE. INSPECT WORK-STRING CONVERTING "abcdefghijklmnopqrstuvwxyz" TO "ABCDEFGHIJKLMNOPQRSTUVWXYZ". CONVERT-TO-LOWERCASE. INSPECT WORK-STRING CONVERTING "ABCDEFGHIJKLMNOPQRSTUVWXYZ" TO "abcdefghijklmnopqrstuvwxyz". VALIDATE-EXTRACTED-DATA. PERFORM VALIDATE-PHONE-FORMAT PERFORM VALIDATE-PRICE-FORMAT PERFORM VALIDATE-DISCOUNT-RANGE. VALIDATE-PHONE-FORMAT. IF EXTRACTED-PHONE NOT = SPACES IF EXTRACTED-PHONE(4:1) = "-" AND EXTRACTED-PHONE(1:3) IS NUMERIC AND EXTRACTED-PHONE(5:4) IS NUMERIC DISPLAY "Phone format: VALID" ELSE DISPLAY "Phone format: INVALID" END-IF END-IF. VALIDATE-PRICE-FORMAT. IF EXTRACTED-PRICE NOT = SPACES IF EXTRACTED-PRICE(1:1) = "$" AND EXTRACTED-PRICE(2:2) IS NUMERIC AND EXTRACTED-PRICE(4:1) = "." AND EXTRACTED-PRICE(5:2) IS NUMERIC DISPLAY "Price format: VALID" ELSE DISPLAY "Price format: INVALID" END-IF END-IF. VALIDATE-DISCOUNT-RANGE. IF EXTRACTED-DISCOUNT NOT = SPACES MOVE EXTRACTED-DISCOUNT(1:2) TO WS-DISCOUNT-NUM IF WS-DISCOUNT-NUM IS NUMERIC AND WS-DISCOUNT-NUM >= 1 AND WS-DISCOUNT-NUM <= 50 DISPLAY "Discount range: VALID" ELSE DISPLAY "Discount range: INVALID" END-IF END-IF. DISPLAY-ADVANCED-RESULTS. DISPLAY "=== Advanced Processing Results ===" DISPLAY "Original: " SOURCE-TEXT DISPLAY "Normalized: " WORK-STRING DISPLAY "Phone: " EXTRACTED-PHONE DISPLAY "Price: " EXTRACTED-PRICE DISPLAY "Discount: " EXTRACTED-DISCOUNT DISPLAY "Product#: " PRODUCT-NUMBER.

Text Processing and Data Validation

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
*> Comprehensive text processing for data validation and cleansing DATA DIVISION. WORKING-STORAGE SECTION. 01 TEXT-VALIDATION-CONTROL. 05 INPUT-RECORD PIC X(300). 05 VALIDATED-RECORD PIC X(300). 05 ERROR-COUNT PIC 9(3) VALUE ZERO. 05 WARNING-COUNT PIC 9(3) VALUE ZERO. 01 FIELD-EXTRACTION. 05 FIELD-COUNT PIC 9(2) VALUE ZERO. 05 FIELD-VALUES OCCURS 20 TIMES. 10 FIELD-DATA PIC X(50). 10 FIELD-TYPE PIC X(10). 10 FIELD-STATUS PIC X(10). 10 ERROR-MESSAGE PIC X(100). 01 CHARACTER-FILTERS. 05 ALLOWED-CHARS PIC X(100) VALUE "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .-_@". 05 FORBIDDEN-CHARS PIC X(50) VALUE "!#$%^&*()+=[]{}|\:;"'<>?/~". 05 NUMERIC-CHARS PIC X(10) VALUE "0123456789". 05 ALPHA-CHARS PIC X(52) VALUE "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz". 01 VALIDATION-STATISTICS. 05 TOTAL-CHARACTERS PIC 9(5) VALUE ZERO. 05 VALID-CHARACTERS PIC 9(5) VALUE ZERO. 05 INVALID-CHARACTERS PIC 9(5) VALUE ZERO. 05 CORRECTED-CHARS PIC 9(5) VALUE ZERO. 01 CLEANSING-RULES. 05 REMOVE-CONTROL-CHARS PIC X VALUE 'Y'. 88 REMOVE-CONTROL VALUE 'Y'. 05 TRIM-WHITESPACE PIC X VALUE 'Y'. 88 TRIM-SPACES VALUE 'Y'. 05 NORMALIZE-CASE PIC X VALUE 'M'. 88 MIXED-CASE VALUE 'M'. 88 UPPER-CASE VALUE 'U'. 88 LOWER-CASE VALUE 'L'. PROCEDURE DIVISION. TEXT-PROCESSING-VALIDATION. PERFORM INITIALIZE-TEXT-PROCESSING PERFORM ANALYZE-INPUT-CHARACTERS PERFORM EXTRACT-AND-VALIDATE-FIELDS PERFORM APPLY-CLEANSING-RULES PERFORM GENERATE-VALIDATION-REPORT. INITIALIZE-TEXT-PROCESSING. MOVE "John Doe, 123 Main St., Anytown ST 12345, john@email.com, (555)123-4567" TO INPUT-RECORD MOVE INPUT-RECORD TO VALIDATED-RECORD MOVE ZERO TO ERROR-COUNT WARNING-COUNT FIELD-COUNT TOTAL-CHARACTERS VALID-CHARACTERS INVALID-CHARACTERS CORRECTED-CHARS. ANALYZE-INPUT-CHARACTERS. MOVE FUNCTION LENGTH(INPUT-RECORD) TO TOTAL-CHARACTERS *> Count valid characters PERFORM VARYING WS-POS FROM 1 BY 1 UNTIL WS-POS > TOTAL-CHARACTERS MOVE INPUT-RECORD(WS-POS:1) TO WS-CHAR *> Check if character is in allowed set MOVE ZERO TO WS-CHAR-FOUND INSPECT ALLOWED-CHARS TALLYING WS-CHAR-FOUND FOR ALL CHARACTERS WS-CHAR IF WS-CHAR-FOUND > ZERO ADD 1 TO VALID-CHARACTERS ELSE ADD 1 TO INVALID-CHARACTERS PERFORM LOG-INVALID-CHARACTER END-IF END-PERFORM DISPLAY "Character Analysis:" DISPLAY "Total: " TOTAL-CHARACTERS DISPLAY "Valid: " VALID-CHARACTERS DISPLAY "Invalid: " INVALID-CHARACTERS. LOG-INVALID-CHARACTER. ADD 1 TO WARNING-COUNT DISPLAY "Invalid character at position " WS-POS ": '" WS-CHAR "' (ASCII " FUNCTION ORD(WS-CHAR) ")". EXTRACT-AND-VALIDATE-FIELDS. *> Split record into fields by comma delimiter UNSTRING INPUT-RECORD DELIMITED BY "," INTO FIELD-DATA(1) FIELD-DATA(2) FIELD-DATA(3) FIELD-DATA(4) FIELD-DATA(5) COUNT IN FIELD-COUNT END-UNSTRING *> Validate each field PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > FIELD-COUNT PERFORM VALIDATE-FIELD-CONTENT END-PERFORM. VALIDATE-FIELD-CONTENT. *> Determine field type and validate accordingly EVALUATE WS-I WHEN 1 *> Name field MOVE "NAME" TO FIELD-TYPE(WS-I) PERFORM VALIDATE-NAME-FIELD WHEN 2 *> Address field MOVE "ADDRESS" TO FIELD-TYPE(WS-I) PERFORM VALIDATE-ADDRESS-FIELD WHEN 3 *> City/State/ZIP field MOVE "LOCATION" TO FIELD-TYPE(WS-I) PERFORM VALIDATE-LOCATION-FIELD WHEN 4 *> Email field MOVE "EMAIL" TO FIELD-TYPE(WS-I) PERFORM VALIDATE-EMAIL-FIELD WHEN 5 *> Phone field MOVE "PHONE" TO FIELD-TYPE(WS-I) PERFORM VALIDATE-PHONE-FIELD END-EVALUATE. VALIDATE-NAME-FIELD. MOVE SPACES TO ERROR-MESSAGE(WS-I) *> Check if field contains only alphabetic and spaces MOVE ZERO TO WS-INVALID-COUNT INSPECT FIELD-DATA(WS-I) TALLYING WS-INVALID-COUNT FOR ALL CHARACTERS FORBIDDEN-CHARS IF WS-INVALID-COUNT > ZERO MOVE "INVALID" TO FIELD-STATUS(WS-I) MOVE "Contains invalid characters for name" TO ERROR-MESSAGE(WS-I) ADD 1 TO ERROR-COUNT ELSE MOVE "VALID" TO FIELD-STATUS(WS-I) END-IF. VALIDATE-EMAIL-FIELD. MOVE SPACES TO ERROR-MESSAGE(WS-I) *> Check for @ symbol MOVE ZERO TO WS-AT-COUNT INSPECT FIELD-DATA(WS-I) TALLYING WS-AT-COUNT FOR ALL CHARACTERS "@" *> Check for dot after @ MOVE ZERO TO WS-DOT-COUNT INSPECT FIELD-DATA(WS-I) TALLYING WS-DOT-COUNT FOR ALL CHARACTERS "." IF WS-AT-COUNT NOT = 1 OR WS-DOT-COUNT < 1 MOVE "INVALID" TO FIELD-STATUS(WS-I) MOVE "Invalid email format" TO ERROR-MESSAGE(WS-I) ADD 1 TO ERROR-COUNT ELSE MOVE "VALID" TO FIELD-STATUS(WS-I) END-IF. VALIDATE-PHONE-FIELD. MOVE SPACES TO ERROR-MESSAGE(WS-I) *> Remove common phone formatting characters MOVE FIELD-DATA(WS-I) TO WS-PHONE-WORK INSPECT WS-PHONE-WORK REPLACING ALL "(" BY SPACE INSPECT WS-PHONE-WORK REPLACING ALL ")" BY SPACE INSPECT WS-PHONE-WORK REPLACING ALL "-" BY SPACE INSPECT WS-PHONE-WORK REPLACING ALL " " BY SPACE *> Check if remaining characters are all numeric MOVE ZERO TO WS-DIGIT-COUNT INSPECT WS-PHONE-WORK TALLYING WS-DIGIT-COUNT FOR ALL CHARACTERS NUMERIC-CHARS IF FUNCTION LENGTH(WS-PHONE-WORK) = 10 AND WS-DIGIT-COUNT = 10 MOVE "VALID" TO FIELD-STATUS(WS-I) ELSE MOVE "INVALID" TO FIELD-STATUS(WS-I) MOVE "Phone must be 10 digits" TO ERROR-MESSAGE(WS-I) ADD 1 TO ERROR-COUNT END-IF. APPLY-CLEANSING-RULES. IF REMOVE-CONTROL PERFORM REMOVE-CONTROL-CHARACTERS END-IF IF TRIM-SPACES PERFORM TRIM-LEADING-TRAILING-SPACES END-IF EVALUATE NORMALIZE-CASE WHEN 'U' PERFORM CONVERT-TO-UPPER-CASE WHEN 'L' PERFORM CONVERT-TO-LOWER-CASE WHEN 'M' PERFORM CONVERT-TO-PROPER-CASE END-EVALUATE. REMOVE-CONTROL-CHARACTERS. *> Remove non-printable control characters PERFORM VARYING WS-POS FROM 1 BY 1 UNTIL WS-POS > FUNCTION LENGTH(VALIDATED-RECORD) MOVE VALIDATED-RECORD(WS-POS:1) TO WS-CHAR IF FUNCTION ORD(WS-CHAR) < 32 OR FUNCTION ORD(WS-CHAR) > 126 MOVE SPACE TO VALIDATED-RECORD(WS-POS:1) ADD 1 TO CORRECTED-CHARS END-IF END-PERFORM. TRIM-LEADING-TRAILING-SPACES. *> Remove leading spaces PERFORM UNTIL VALIDATED-RECORD(1:1) NOT = SPACE MOVE VALIDATED-RECORD(2:299) TO VALIDATED-RECORD(1:299) MOVE SPACE TO VALIDATED-RECORD(300:1) END-PERFORM *> Remove trailing spaces PERFORM VARYING WS-POS FROM 300 BY -1 UNTIL WS-POS < 1 IF VALIDATED-RECORD(WS-POS:1) NOT = SPACE EXIT PERFORM ELSE MOVE SPACE TO VALIDATED-RECORD(WS-POS:1) END-IF END-PERFORM. CONVERT-TO-PROPER-CASE. *> Convert first letter of each word to uppercase MOVE 'Y' TO WS-NEW-WORD PERFORM VARYING WS-POS FROM 1 BY 1 UNTIL WS-POS > FUNCTION LENGTH(VALIDATED-RECORD) MOVE VALIDATED-RECORD(WS-POS:1) TO WS-CHAR IF WS-CHAR = SPACE MOVE 'Y' TO WS-NEW-WORD ELSE IF WS-NEW-WORD = 'Y' *> Convert to uppercase INSPECT WS-CHAR CONVERTING "abcdefghijklmnopqrstuvwxyz" TO "ABCDEFGHIJKLMNOPQRSTUVWXYZ" MOVE WS-CHAR TO VALIDATED-RECORD(WS-POS:1) MOVE 'N' TO WS-NEW-WORD ELSE *> Convert to lowercase INSPECT WS-CHAR CONVERTING "ABCDEFGHIJKLMNOPQRSTUVWXYZ" TO "abcdefghijklmnopqrstuvwxyz" MOVE WS-CHAR TO VALIDATED-RECORD(WS-POS:1) END-IF END-IF END-PERFORM. GENERATE-VALIDATION-REPORT. DISPLAY "=== Text Processing Validation Report ===" DISPLAY "Original Record: " INPUT-RECORD DISPLAY "Validated Record: " VALIDATED-RECORD DISPLAY "Total Errors: " ERROR-COUNT DISPLAY "Total Warnings: " WARNING-COUNT DISPLAY "Characters Corrected: " CORRECTED-CHARS DISPLAY "" DISPLAY "Field Validation Results:" PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > FIELD-COUNT DISPLAY "Field " WS-I " (" FIELD-TYPE(WS-I) "): " FIELD-STATUS(WS-I) IF FIELD-STATUS(WS-I) = "INVALID" DISPLAY " Error: " ERROR-MESSAGE(WS-I) END-IF DISPLAY " Data: " FIELD-DATA(WS-I) DISPLAY "" END-PERFORM.

Best Practices and Performance Optimization

CHARACTER Processing Guidelines:

  • Use INSPECT for efficient character-level operations instead of manual loops
  • Combine multiple character operations in single INSPECT statements when possible
  • Pre-validate string lengths before character processing to prevent overflow
  • Cache frequently used character sets and patterns in working storage
  • Use reference modification for precise character positioning and extraction
  • Implement character validation early in processing pipelines for data quality
  • Consider performance implications of complex character transformation operations
  • Document character encoding assumptions and requirements for international data
  • Use function-based approaches for complex character analysis when available
  • Implement comprehensive error handling for character processing edge cases

Comprehensive FAQ

Q: What's the difference between CHARACTER and CHARACTERS in INSPECT?

CHARACTER and CHARACTERS are functionally equivalent in INSPECT statements - both refer to individual character processing. The choice between them is typically stylistic or based on readability. Some programmers prefer CHARACTERS for multiple character operations and CHARACTER for single character operations, though both work the same way technically.

Q: How do I handle case-insensitive character operations?

For case-insensitive operations, include both uppercase and lowercase versions of characters in your INSPECT statement. For example: INSPECT STRING TALLYING COUNT FOR ALL CHARACTERS "aA" "eE" "iI" "oO" "uU". Alternatively, convert the entire string to one case first, then perform the operation.

Q: Can I use INSPECT with special characters and punctuation?

Yes, INSPECT works with all printable characters including special characters and punctuation. You can search for, count, or replace characters like "@", "#", "$", "%", etc. Be careful with quotes and apostrophes - you may need to use different quote styles or hexadecimal values for these characters.

Q: How do I validate that a string contains only specific characters?

Create a validation pattern with allowed characters and use INSPECT to count characters not in that set. If the count is zero, the string contains only allowed characters. You can also use INSPECT to count the total characters and compare it with the count of valid characters.

Q: What's the best way to remove unwanted characters from strings?

Use INSPECT REPLACING to substitute unwanted characters with spaces or other acceptable characters. For complete removal, replace with spaces then use string functions to compress spaces. For multiple unwanted characters, use multiple INSPECT statements or create a comprehensive replacement pattern.

Q: How do I handle Unicode or international characters?

COBOL's character handling depends on the system's character encoding. For Unicode support, use NATIONAL data types where available. For international characters in standard COBOL, ensure your system supports the required character set and test thoroughly with actual international data to verify proper handling of extended character sets.

Interactive Quiz

Test Your CHARACTER and CHARACTERS Knowledge

1. Which statement would count vowels in a string case-insensitively?

2. What's the best way to replace multiple consecutive spaces with single spaces?

3. How do you convert a string to proper case (first letter uppercase)?

Answers: 1-B, 2-D, 3-B