Compaq COBOL
User Manual


Previous Contents Index

5.1.3 Using the POINTER Phrase

Although the STRING statement normally starts scanning at the leftmost position of the receiving item, the POINTER phrase makes it possible to start scanning at another point within the item. The scanning, however, continues left to right. Consider the following example:


MOVE 5 TO P. 
STRING FIELD1A FIELD1B DELIMITED BY SIZE 
        INTO FIELD2 WITH POINTER P. 

The value of P determines the starting character position in the receiving item. In this example, the 5 in P causes the program to move the first character of FIELD1A into character position 5 of FIELD2 (the leftmost character position of the receiving item is character position 1), and leave positions 1 to 4 unchanged.

When the STRING operation is complete, P points to one character position beyond the last character replaced in the receiving item. If FIELD1A and FIELD1B are both four characters long, P contains a value of 13 (5+4+4) when the operation is complete (assuming that FIELD2 is at least 13 characters long).

5.1.4 Using the OVERFLOW Phrase

When the SIZE option of the DELIMITED BY phrase controls the STRING operation, and the pointer value is either known or the POINTER phrase is not used, you can add the PICTURE sizes of sending items together at program development time to see if the receiving item is large enough to hold the sending items. However, if the DELIMITED BY phrase contains a literal or an identifier, or if the pointer value is not predictable, it can be difficult to tell whether or not the size of the receiving item will be large enough at run time. If the size of the receiving item is not large enough, an overflow can occur.

An overflow occurs when the receiving item is full and the program is either about to move a character from a sending item or is considering a new sending item. Overflow can also occur if, during the initialization of the statement, the pointer contains a value that is either less than 1 or greater than the length of the receiving item. In this case, the program moves no data to the receiving item and terminates the operation immediately.

The ON OVERFLOW phrase at the end of the STRING statement tests for an overflow condition:


STRING FIELD1A FIELD1B DELIMITED BY "C" 
        INTO FIELD2 WITH POINTER PNTR 
        ON OVERFLOW GO TO 200-STRING-OVERFLOW. 

The ON OVERFLOW phrase cannot distinguish the overflow caused by a bad initial value in the pointer from the overflow caused by a receiving item that is too short. Only a separate test preceding the STRING statement can distinguish between the two.

Additionally, even if an overflow condition does not exist, you can use the NOT ON OVERFLOW phrase to branch to or execute other sections of code.

Example 5-2 illustrates the overflow condition.

Example 5-2 Sample Overflow Condition

DATA DIVISION. 
     . 
     . 
     . 
01 FIELD1 PIC XXX VALUE "ABC". 
01 FIELD2 PIC XXXX. 
PROCEDURE DIVISION. 
           . 
           . 
           . 
1.    STRING FIELD1 QUOTE DELIMITED BY SIZE INTO FIELD2 
             ON OVERFLOW DISPLAY "overflow at 1". 
2.    STRING FIELD1 FIELD1 DELIMITED BY SIZE INTO FIELD2 
             ON OVERFLOW DISPLAY "overflow at 2". 
3.    STRING FIELD1 FIELD1 DELIMITED BY "C" INTO FIELD2 
             ON OVERFLOW DISPLAY "overflow at 3". 
4.    STRING FIELD1 FIELD1 FIELD1 FIELD1 
             DELIMITED BY "B" INTO FIELD2 ON OVERFLOW DISPLAY "overflow at 4". 
5.    STRING FIELD1 FIELD1 "D" DELIMITED BY "C" 
             INTO FIELD2 ON OVERFLOW DISPLAY "overflow at 5". 
6.    MOVE 2 TO P. 
 
      MOVE ALL QUOTES TO FIELD2. 
 
      STRING FIELD1 "AC" DELIMITED BY "C" 
             INTO FIELD2 WITH POINTER P ON OVERFLOW DISPLAY "overflow at 6". 

The STRING statement numbers in Example 5-2 point to the line number results shown in Table 5-1.

Table 5-1 Results of Sample Overflow Statements
Value of FIELD2 After the STRING Operation Overflow?
1. ABC" No
2. ABCA Yes
3. ABAB No
4. AAAA No
5. ABAB Yes
6. "ABA No

5.1.5 Common STRING Statement Errors

The following are common errors made when writing STRING statements:

5.2 Separating Data Using the UNSTRING Statement

The UNSTRING statement disperses the contents of a single sending item into one or more receiving items.

The statement has many forms; the simplest is equivalent in function to a nonnumeric MOVE statement. Consider the following example:


UNSTRING FIELD1 INTO FIELD2. 

Regardless of the relative sizes of the two items, the sample statement is equivalent to the following MOVE statement:


MOVE FIELD1 TO FIELD2. 

The sending item (FIELD1) can be either (1) a group item, or (2) an alphanumeric or alphanumeric edited elementary item. The receiving item (FIELD2) can be alphabetic, alphanumeric, or numeric, but it cannot specify any type of editing.

If the receiving item is numeric, it must be DISPLAY usage. The PICTURE character-string of a numeric receiving item can contain any of the legal numeric description characters except P and the editing characters. The UNSTRING statement moves the sending item to the numeric receiving item as if the sending item had been described as an unsigned integer. It automatically truncates or zero-fills as required.

If the receiving item is not numeric, the statement follows the rules for elementary nonnumeric MOVE statements. It left-justifies the data in the receiving item, truncating or space-filling as required. If the data description of the receiving item contains a JUSTIFIED clause, the compiler right-justifies the data, truncating or space-filling to the left as required.

5.2.1 Multiple Receiving Items

The UNSTRING statement can disperse one sending item into several receiving items. Consider the following example of the UNSTRING statement written with multiple receiving items:


UNSTRING FIELD1 INTO FIELD2A FIELD2B FIELD2C. 

The compiler-generated code performs the UNSTRING operation by scanning across FIELD1, the sending item, from left to right. When the number of characters scanned equals the number of characters in the receiving item, the scanned characters are moved into that item and the next group of characters is scanned for the next receiving item.

If each of the receiving items in the preceding example (FIELD2A, FIELD2B, and FIELD2C) is 5 characters long, and FIELD1 is 15 characters long, FIELD1 is scanned until the number of characters scanned equals the size of FIELD2A (5). Those first five characters are moved to FIELD2A, and scanning is resumed at the sixth character position in FIELD1. Next, FIELD1 is scanned from character position 6, until the number of scanned characters equals the size of FIELD2B (five). The sixth through the tenth characters are then moved to FIELD2B, and the scanner is set to the next (eleventh) character position in FIELD1. For the last move in this example, characters 11 to 15 of FIELD1 are moved into FIELD2C.

Each data movement acts as an individual MOVE statement, the sending item of which is an alphanumeric item equal in size to the receiving item. If the receiving item is numeric, the move operation converts the data to numeric form. For example, consider what would happen if the items under discussion had the data descriptions and were manipulating the values shown in Table 5-2.

Table 5-2 Values Moved into the Receiving Items Based on the Sending Item Value
FIELD1
PIC X(15)
VALUE IS:
FIELD2A
PIC X(5)
FIELD2B
PIC S9(5)
LEADING SEPARATE
FIELD2C
PIC S999V99
ABCDE1234512345 ABCDE +12345 3450{
XXXXX0000100123 XXXXX +00001 1230{

FIELD2A is an alphanumeric item. Therefore, the statement simply conducts an elementary nonnumeric move with the first five characters.

FIELD2B, however, has a leading separate sign that is not included in its size. Thus, the compiler moves only five numeric characters and generates a positive sign (+) in the separate sign position.

FIELD2C has an implied decimal point with two character positions to the right of it, plus an overpunched sign on the low-order digit. The sending item should supply five numeric digits. However, because the sending item is alphanumeric, the compiler treats it as an unsigned integer; it truncates the two high-order digits and supplies two zero digits for the decimal positions. Furthermore, it supplies a positive overpunch sign, making the low-order digit a +0 (ASCII { ). There is no way to have the UNSTRING statement recognize a sign character or a decimal point in the sending item in a single statement.

If the sending item is shorter than the sum of the sizes of the receiving items, the compiler ignores the remaining receiving items. If the compiler reaches the end of the sending item before it reaches the end of one of the receiving items, it moves the scanned characters into that receiving item. It either left-justifies and fills the remaining character positions with spaces for alphanumeric data, or else it decimal point-aligns and zero-fills the remaining character positions for numeric data.

Consider the following statement with reference to the corresponding PICTURE character-strings and values in Table 5-3:


UNSTRING FIELD1 INTO FIELD2A FIELD2B. 

FIELD2A is a 3-character alphanumeric item. It receives the first three characters of FIELD1 (ABC) in every operation. FIELD2B, however, runs out of characters every time before filling, as Table 5-3 illustrates.

Table 5-3 Handling a Short Sending Item
FIELD1
PIC X(6)
VALUE IS:
FIELD2B
PICTURE IS:
FIELD2B
Value After UNSTRING Operation
ABCDEF XXXXX DEF
  S99999 0024F
ABC246 S9V999 600{
  S9999 LEADING SEPARATE +0246

5.2.2 Controlling Moved Data Using the DELIMITED BY Phrase

The size of the data to be moved can be controlled by a delimiter, rather than by the size of the receiving item. The DELIMITED BY phrase supplies the delimiter characters.

UNSTRING delimiters can be literals, figurative constants (including ALL literal), or identifiers (identifiers can even be subscripted data names). This section describes the use of these three types of delimiters. Subsequent sections cover multiple delimiters, the COUNT phrase, and the DELIMITER phrase.

Consider the following sample UNSTRING statement with the figurative constant SPACE as a delimiter:


UNSTRING FIELD1 DELIMITED BY SPACE 
         INTO FIELD2. 

In this example, the compiler scans the sending item (FIELD1), searching for a space character. If it encounters a space, it moves all of the scanned (nonspace) characters that precede that space to the receiving item (FIELD2). If it finds no space character, it moves the entire sending item. When the compiler has determined the size of the sending item, it moves the contents of that item following the rules for the MOVE statement, truncating or zero-filling as required.

Table 5-4 shows the results of the following UNSTRING operation that uses a literal asterisk delimiter:


UNSTRING FIELD1 DELIMITED BY "*" 
         INTO FIELD2. 

Table 5-4 Results of Delimiting with an Asterisk
FIELD1
PIC X(6)
VALUE IS:
FIELD2
PICTURE IS:
FIELD2
Value After
UNSTRING
  XXX ABC
ABCDEF X(7) ABCDEF
  XXX JUSTIFIED DEF
****** XXX ###
*ABCDE XXX ###
A***** XXX JUSTIFIED ##A
246*** S9999 024F
12345* S9999 TRAILING SEPARATE 2345+
2468** S999V9 LEADING SEPARATE +4680
*246** 9999 0000


Legend: # = space

If the delimiter matches the first character in the sending item, the compiler considers the size of the sending item to be zero. The operation still takes place, however, and fills the receiving item with spaces (if it is nonnumeric) or zeros (if it is numeric).

A delimiter can also be applied to an UNSTRING statement that has multiple receiving items:


UNSTRING FIELD1 DELIMITED BY SPACE 
         INTO FIELD2A FIELD2B. 

The compiler generates code that scans FIELD1 searching for a character that matches the delimiter. If it finds a match, it moves the scanned characters to FIELD2A and sets the scanner to the next character position to the right of the character that matched. The compiler then resumes scanning FIELD1 for a character that matches the delimiter. If it finds a match, it moves all of the characters between the character that first matched the delimiter and the character that matched on the second scan, and sets the scanner to the next character position to the right of the character that matched.

The DELIMITED BY phrase handles additional items in the same manner as it handled FIELD2B.

Table 5-5 illustrates the results of the following delimited UNSTRING operation into multiple receiving items:


UNSTRING FIELD1 DELIMITED BY "*" 
         INTO FIELD2A FIELD2B. 

Table 5-5 Results of Delimiting Multiple Receiving Items
  Values After UNSTRING Operation
FIELD1
PIC X(8)
VALUE IS:
FIELD2A
PIC X(3)
FIELD2B
PIC X(3)
ABC*DEF* ABC DEF
ABCDE*FG ABC FG#
A*B**** A## B##
*AB*CD** ### AB#
**ABCDEF ### ###
A*BCDEFG A## BCD
ABC**DEF ABC ###
A******B A## ###


Legend: # = space

The previous examples illustrate the limitations of a single-character delimiter. To overcome these limitations, a delimiter of more than one character or a delimiter preceded by the word ALL may be used.

Table 5-6 shows the results of the following UNSTRING operation using a 2-character delimiter:


UNSTRING FIELD1 DELIMITED BY "**" 
         INTO FIELD2A FIELD2B. 

Table 5-6 Results of Delimiting with Two Asterisks
  Values After UNSTRING Operation
FIELD1
PIC X(8)
VALUE IS:
FIELD2A
PIC XXX
FIELD2B
PIC XXX
JUSTIFIED
ABC**DEF ABC DEF
A*B*C*D* A*B ###
AB***C*D AB# C*D
AB**C*D* AB# *D*
AB**CD** AB# #CD
AB***CD* AB# CD*
AB*****CD AB# ###


Legend: # = space

Unlike the STRING statement, the UNSTRING statement accepts the ALL literal as a delimiter. When the word ALL precedes the delimiter, the action of the UNSTRING statement remains essentially the same as with one delimiter until the scanning operation finds a match. At this point, the compiler scans farther, looking for additional consecutive strings of characters that also match the delimiter item. It considers the ALL delimiter to be one, two, three, or more adjacent repetitions of the delimiter item. Table 5-7 shows the results of the following UNSTRING operation using an ALL delimiter:


UNSTRING FIELD1 DELIMITED BY ALL "*" 
         INTO FIELD2A FIELD2B. 

Table 5-7 Results of Delimiting with ALL Asterisks
  Values After UNSTRING Operation
FIELD1
PIC X(8)
VALUE IS:
FIELD2A
PIC XXX
FIELD2B
PIC XXX
JUSTIFIED
ABC*DEF* ABC DEF
ABC**DEF ABC DEF
A******F A## ##F
A*F***** A## ##F
A*CDEFG A## EFG


Legend: # = space

Table 5-8 shows the results of the following UNSTRING operation that combines ALL with a 2-character delimiter:


UNSTRING FIELD1 DELIMITED BY ALL "**" 
         INTO FIELD2A FIELD2B. 

Table 5-8 Results of Delimiting with ALL Double Asterisks
  Values After UNSTRING Operation
FIELD1
PIC X(8)
VALUE IS:
PIC XX PIC XXX
JUSTIFIED
ABC**DEF ABC DEF
AB**DE** AB# #DE
A***D*** A## #*D
A******* A## ##*


Legend: # = space

In addition to unchangeable delimiters, such as literals and figurative constants, delimiters can be designated by identifiers. Identifiers permit variable delimiting. Consider the following sample statement:


UNSTRING FIELD1 DELIMITED BY DEL1 
         INTO FIELD2A FIELD2B. 

The data name DEL1 must be alphanumeric; it can be either a group or an elementary item. If the delimiter contains a subscript, the subscript may vary as a side effect of the UNSTRING operation.


Previous Next Contents Index