Michael Coughlan

Home > Other > Michael Coughlan > Page 46


  UNSTRING SupplierRec DELIMITED BY ","

  INTO Supplier-Code COUNT IN SuppCodeCount

  Supplier-Name COUNT IN SuppNameCount

  Supplier-Address COUNT IN SuppAdrCount

  END-UNSTRING

  373

  Chapter 15 ■ String Manipulation

  The UNSTRING Verb

  The metalanguage for the UNSTRING verb is given in Figure 15-7.

  Figure 15-7. Metalanguage for the UNSTRING verb

  UNSTRING copies characters from the source string to the destination string until a condition is encountered that terminates data movement. When data movement ends for a particular destination string, the next destination string becomes the receiving area, and characters are copied into it until once again a terminating condition is encountered.

  Characters are copied from the source string to the destination strings according to the rules for MOVE, with space filling or truncation as necessary.

  Strictly speaking, END-UNSTRING is only required to delimit the scope of the OVERFLOW statement block. You will notice, however, that I have a tendency to use it to indicate the end of every UNSTRING statement. This is just a personal preference.

  Data-Movement Termination

  When you use the DELIMITED BY clause, data movement from the source string to the current destination string ends when either of the following occurs:

  • A delimiter is encountered in the source string

  • The end of the source string is reached

  When the DELIMITED BY clause is not used, data movement from the source string to the current destination

  string ends when either of these is true:

  • The destination string is full.

  • The end of the source string is reached.

  UNSTRING Termination

  The UNSTRING statement terminates in the following cases:

  • All the characters in the source string have been examined.

  • All the destination strings have been processed.

  • Some error condition is encountered (such as the pointer pointing outside the source string).

  374

  Chapter 15 ■ String Manipulation

  UNSTRING Clauses

  As you can see by examining the metalanguage, the operation of UNSTRING is modified by a number of clauses. These clauses affect the operation of UNSTRING as follows:

  DELIMITED BY: When the DELIMITED BY clause is used, characters are examined in the

  source string and copied to the current destination string until one of the specified

  delimiters is encountered in the source string or the end the source string is reached.

  If there is not enough room in the destination string to take all the characters sent to it

  from the source string, the remaining characters are truncated/lost. When the delimiter

  is encountered in the source string, the next destination string becomes current, and

  characters are transferred into it from the source string. Delimiters are not transferred or

  counted in CharCounter#i.

  ON OVERFLOW: When ON OVERFLOW activates, the statement block following it is executed.

  ON OVERFLOW activates if

  • The unstring pointer (Pointer#i) is not pointing to a character position within the

  source string when UNSTRING executes (that is, Pointer#i is 0 or is greater than the size of

  the string).

  • All the destination strings have been processed, but there are still valid unexamined

  characters in the source string.

  The statements following NOT ON OVERFLOW are executed if UNSTRING is about to terminate

  successfully.

  COUNT IN: The COUNT IN clause is associated with a particular destination string and holds

  a count of the number of characters passed to the destination string, regardless of whether

  they were truncated.

  DELIMITER IN: A DELIMITER IN clause is associated with a particular destination string.

  HoldDelim$i holds the delimiter that was encountered in the source string. If the DELIMITER

  IN phrase is used with the ALL phrase, then only one occurrence of the delimiter is moved

  to HoldDelim$i.

  TALLYING IN: Only one TALLYING clause can be used with each UNSTRING. It holds a count

  of the number of destination strings affected by the UNSTRING operation.

  WITH POINTER: When the WITH POINTER clause is used, the Pointer#i data item holds the

  position of the next non-delimiter character to be examined in the source string. Pointer#i

  must be large enough to hold a value one greater than the size of the source string, because

  when UNSTRING ends, it will be pointing to one character position beyond the end of the string.

  ALL: When the ALL phrase is used, contiguous delimiters are treated as if only one delimiter

  had been encountered. If ALL is not used, contiguous delimiters result in spaces being sent

  to some of the destination strings.

  Notes on UNSTRING

  Bear the following in mind when you use UNSTRING:

  • Where a literal can be used, any figurative constant can be used except the ALL literal

  figurative constant.

  • When a figurative constant is used, it is one character long.

  375

  Chapter 15 ■ String Manipulation

  • The delimiter is moved into HoldDelim$i according to the rules for MOVE.

  • The DELIMITER IN and COUNT IN phrases may be specified only if the DELIMITED BY

  phrase is used.

  Language Knowledge Examples

  This section presents a number of UNSTRING examples. These are not real-world examples but are rather intended to show how UNSTRING and its clauses operate.

  UNSTRING: Demonstrating the COUNT IN Clause

  Listing 15-5 demonstrates how to chop a string into separate strings based on a delimiter and how to keep a count of the number of characters transferred to each destination string. Note that DestStr2 is larger than the data copied to it and so is space filled. DestStr3 is too small to hold the characters transferred to it, so they are truncated; but the count still notes how many characters were transferred (08). The count for DestStr4 seems incorrect, but the literal assigned to xString is not long enough to fill it and so it is space filled. When UNSTRING copies “of sweet silent” to DestStr4, it copies these trailing spaces; they can’t all fit into DestStr4 and so are truncated but counted.

  Listing 15-5. UNSTRING Example 1

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing15-5.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 xString PIC X(45) VALUE "When,to the,sessions,of sweet silent".

  01 DestinationStrings.

  02 DestStr1 PIC X(4).

  02 DestStr2 PIC X(10).

  02 DestStr3 PIC X(3).

  02 DestStr4 PIC X(18).

  01 CharCounts.

  02 CCount PIC 99 OCCURS 4 TIMES.

  PROCEDURE DIVISION.

  Begin.

  UNSTRING xString delimited by ","

  INTO DestStr1 COUNT IN CCount(1)

  DestStr2 COUNT IN CCount(2)

  DestStr3 COUNT IN CCount(3)

  DestStr4 COUNT IN CCount(4)

  END-UNSTRING

  DISPLAY DestStr1 " = " CCount(1)

  DISPLAY DestStr2 " = " CCount(2)

  DISPLAY DestStr3 " = " CCount(3)

  DISPLAY DestStr4 " = " CCount(4)

  STOP RUN.

  376

  Chapter 15 ■ String Manipulation

  UNSTRING: Demonstrating ON OVERFLOW and the Effect of Delimiters

  Listing 15-6 contains three UNSTRING examples. Example 2 demonstrates the activation of the ON OVERFLOW clause.

  Because no delimiter is specified, all the text in DateStr is eligible fo
r transfer; and as each destination item is filled, the next one becomes the current target. There are not enough destination items to take all the data: the remaining characters (“19” and the trailing spaces) are eligible for transfer, but there are no destination strings left to take them.

  So, ON OVERFLOW activates, and the message “Characters unexamined” is displayed.

  Listing 15-6. The ON OVERFLOW Clause and the Effect of Delimiters

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing15-6.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 DateStr PIC X(15).

  01 DateRec.

  02 DayStr PIC XX.

  02 MonthStr PIC XX.

  02 YearStr PIC X(4).

  PROCEDURE DIVISION.

  Begin.

  *>Unstring example 2

  MOVE "19-08-2012" TO DateStr

  UNSTRING DateStr INTO DayStr, MonthStr, YearStr

  ON OVERFLOW DISPLAY "Characters unexamined"

  END-UNSTRING

  DISPLAY DayStr SPACE MonthStr SPACE YearStr

  DISPLAY "__________________________"

  DISPLAY SPACES

  *>Unstring example 3

  MOVE "25-07-2013lost" TO DateStr.

  UNSTRING DateStr DELIMITED BY "-"

  INTO DayStr, MonthStr, YearStr

  ON OVERFLOW DISPLAY "Characters unexamined"

  END-UNSTRING.

  DISPLAY DayStr SPACE MonthStr SPACE YearStr

  DISPLAY "__________________________"

  DISPLAY SPACES

  *>Unstring example 4

  MOVE "30end06end2014" TO DateStr

  UNSTRING DateStr DELIMITED BY "end"

  INTO DayStr, MonthStr, YearStr

  ON OVERFLOW DISPLAY "Characters unexamined"

  END-UNSTRING

  DISPLAY DayStr SPACE MonthStr SPACE YearStr

  STOP RUN.

  377

  Chapter 15 ■ String Manipulation

  Example 3 demonstrates the difference when a delimiter is specified. ON OVERFLOW does not activate in this case because all the characters have been copied to the destination strings. UNSTRING tries to copy “2013lost” into YearStr, but because there is not sufficient room, some of the transferred characters are truncated.

  Example 4 demonstrates that the delimiter does not have to be a single character. It can be a word or any other group of characters.

  UNSTRING: The Effect of the ALL Delimiter

  Listing 15-7 also contains three UNSTRING examples. Example 5 demonstrates the use of the ALL delimiter, which treats successive occurrences of a delimiter as one occurrence. This is contrasted with Example 6, where the same delimiter configuration is used but the ALL phrase is omitted. In this example, each occurrence of the delimiter is treated as separate instance; the result is shown in the following storage schematic.

  Listing 15-7. The ALL Delimiter and the DELIMITER IN Phrase

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing15-7.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 DateStr PIC X(15).

  01 DateRec.

  02 DayStr PIC XX.

  02 MonthStr PIC XX.

  02 YearStr PIC X(4).

  01 Delims.

  02 HoldDelim OCCURS 3 TIMES PIC X.

  PROCEDURE DIVISION.

  Begin.

  *>Unstring example 5

  MOVE "15---07--2013" TO DateStr.

  UNSTRING DateStr DELIMITED BY ALL "-"

  INTO DayStr, MonthStr, YearStr

  ON OVERFLOW DISPLAY "Characters unexamined"

  378

  Chapter 15 ■ String Manipulation

  END-UNSTRING

  DISPLAY DayStr SPACE MonthStr SPACE YearStr

  DISPLAY "__________________________"

  DISPLAY SPACES

  *>Unstring example 6

  MOVE "15---07--2013" TO DateStr.

  UNSTRING DateStr DELIMITED BY "-"

  INTO DayStr

  MonthStr

  YearStr

  ON OVERFLOW DISPLAY "Characters unexamined"

  END-UNSTRING

  DISPLAY DayStr SPACE MonthStr SPACE YearStr

  DISPLAY "__________________________"

  DISPLAY SPACES

  *>Unstring example 7

  MOVE "15/07-----2013@" TO DateStr

  UNSTRING DateStr DELIMITED BY "/" OR "@" OR ALL "-"

  INTO DayStr DELIMITER in HoldDelim(1)

  MonthStr DELIMITER in HoldDelim(2)

  YearStr DELIMITER in HoldDelim(3)

  ON OVERFLOW DISPLAY "Characters unexamined"

  END-UNSTRING

  DISPLAY HoldDelim(1) " delimits " DayStr

  DISPLAY HoldDelim(2) " delimits " MonthStr

  DISPLAY HoldDelim(3) " delimits " YearStr

  STOP RUN.

  Example 7 shows how you can use the DELIMITER IN clause to store a delimiter that causes character transfer to cease for a particular destination field.

  String-Splitting Program

  The examples so far have shown you aspects of the UNSTRING verb’s operation. Listing 15-8 is a more real-world example. The problem specification is as follows: Write a program that accepts a person’s full name from the user and reduces it to the initials of the first and middle names followed by the surname. For instance, William Henry Ford Power becomes W. H. F. Power.

  Listing 15-8. UNSTRING and STRING Used in Combination

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing15-8.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 OldName PIC X(80).

  379

  Chapter 15 ■ String Manipulation

  01 TempName.

  02 NameInitial PIC X.

  02 FILLER PIC X(19).

  01 NewName PIC X(30).

  01 UnstrPtr PIC 99.

  88 NameProcessed VALUE 81.

  01 StrPtr PIC 99.

  PROCEDURE DIVISION.

  ProcessName.

  DISPLAY "Enter a name - " WITH NO ADVANCING

  ACCEPT OldName

  MOVE 1 TO UnstrPtr, StrPtr

  UNSTRING OldName DELIMITED BY ALL SPACES

  INTO TempName WITH POINTER UnstrPtr

  END-UNSTRING

  PERFORM UNTIL NameProcessed

  STRING NameInitial "." SPACE DELIMITED BY SIZE

  INTO NewName WITH POINTER StrPtr

  END-STRING

  UNSTRING OldName DELIMITED BY ALL SPACES

  INTO TempName WITH POINTER UnstrPtr

  END-UNSTRING

  END-PERFORM

  STRING TempName DELIMITED BY SIZE

  INTO NewName WITH POINTER StrPtr

  END-STRING

  DISPLAY "Processed name = " NewName

  STOP RUN.

  Reference Modification

  Reference modification is a special COBOL facility that allows you to treat any USAGE IS DISPLAY item as if it were an array of characters but it defines access to the characters in a special way. To access substrings using reference modification, as shown in the metalanguage in Figure 15-8, you must specify the following:

  • The name of the data item (DataItemName) to be referenced

  • The start-character position of the substring (StartPos)

  • The number of characters in the substring (SubStrLength)

  Figure 15-8. Metalanguage syntax for reference modification

  380

  Chapter 15 ■ String Manipulation

  The metalanguage syntax is modified by the following sematic rules:

  • StartPos is the character position of the first character in the substring, and SubStrLength

  is the number of characters in the substring. StartPos and SubStrLength must each be a

  positive integer or an expression that evaluates to one.

  • DataItemName can be subscripte
d and/or qualified.

  • DataItemName can be the alphanumeric value returned by a function.

  • As indicated by the square brackets, SubStrLength may be omitted, in which case the

  substring from StartPos to the end of the string is assumed.

  • You can use reference modification almost anywhere an alphanumeric data item is permitted.

  To get a feel for the way reference modification works, let’s look at some examples. You start with some abstract examples and then see how you can use reference modification in a more practical situation.

  The three DISPLAYs in Example 15-7 use reference modification to display substrings of xString. The storage schematic shows how each example extracts the substring from xString:

  • DISPLAY xString(11:5) displays a substring of five characters starting at the position of the

  eleventh character.

  • DISPLAY xString(17:SubStrSize) demonstrates that you can use a numeric data item in

  place of the literal and displays eight characters starting with the seventeenth.

  • DISPLAY xString(StartPos:) shows that when you omit SubStrLength, the substring

  consists of the characters from the start character to the end of the string.

  Example 15-7. Extracting a Substring Using Reference Modification

  381

  Chapter 15 ■ String Manipulation

  The two DISPLAY statements in Example 15-8 demonstrate the other ways of defining the substring. The MOVE

  statement shows how you can use reference modification to insert characters into a string:

  • DISPLAY xString(12:SubstrSize - 5) shows that you can use an arithmetic expression as

  SubStrLength.

  • DISPLAY FUNCTION UPPER-CASE(xString)(Startpos - 7 : 4) demonstrates that you can

  apply reference modification to a function result. It also shows that StartPos may be an

  arithmetic expression.

  • MOVE " text insert " TO XString(31:6) demonstrates how to use reference modification

  to insert text into a string. Note that the SubStrLength given specifies the number of characters

  in the string that will be overwritten. For instance, in this example only 6 characters are

 

‹ Prev