Book Read Free

Michael Coughlan

Page 47

by Beginning COBOL for Programmers-Apress (2014) (pdf)


  overwritten, even though there are 13 characters in the moved text.

  Example 15-8. Applying Reference Modification to an Alphanumeric String

  Example 15-9 shows how to apply reference modification to the numeric data item nString and the edited

  numeric data item enString:

  • In nString, reference modification is used to display the dollars and cents parts of a

  numeric value.

  • In enString, reference modification is used to overwrite the check-security asterisks with

  the @ symbol. Note that ALL "@" is a figurative constant that is used to fill the four character positions specified by the reference modifier.

  382

  Chapter 15 ■ String Manipulation

  Example 15-9. Applying Reference Modification to Numeric Data Items

  Intrinsic Functions

  User-defined functions of one sort or another are a standard part of many programming languages. The ANS 85

  version of COBOL does not support user-defined functions, but it has introduced a library of standard functions called intrinsic functions.

  Intrinsic functions fall into three broad categories: date functions, numeric functions, and string functions.

  Because this chapter is about string manipulation, I discuss the string functions in some detail. I also look at the date functions and some of the numeric functions that I have found particularly useful. For the remaining functions you should consult your implementer manual.

  Using Intrinsic Functions

  Like a function in another language, an intrinsic function is replaced by the function result in the position where the function occurs. Wherever you can use a literal, you can use an intrinsic function that returns a result of the same type.

  An intrinsic function consists of three parts:

  • The start of the function is signalled by the FUNCTION keyword.

  • The FUNCTION keyword is followed by the name of the function.

  • The name of the function is immediately followed by a bracketed list of

  parameters or arguments.

  383

  Chapter 15 ■ String Manipulation

  • The intrinsic function template is

  FUNCTION FunctionName(Parameter)

  where FunctionName is the name of the function and Parameter is one or

  more parameters/arguments supplied to the function.

  For instance, the following examples show how to use intrinsic functions in a number of different contexts. In some cases, the result of the function is assigned to a data item; in others (as in the first example), it is used directly in the place of a literal or data item. Sometimes the parameters/arguments are numeric, and other times they are alphabetic. Some functions use only one parameter, others take multiple parameters, and still others do not require a parameter:

  DISPLAY FUNCTION UPPER-CASE("this will be in upper case").

  MOVE FUNCTION ORD("A") TO OrdPos

  MOVE FUNCTION RANDOM(SeedValue) TO RandomNumber

  MOVE FUNCTION RANDOM TO NextRndNumber

  COMPUTE Result = FUNCTION MOD(25, 10)

  MOVE FUNCTION ORD-MAX(12 23 03 78 65) TO MaxOrdPos

  When you use intrinsic functions, you must bear in mind a number of things:

  • Intrinsic functions return a result of Alphanumeric, Numeric (includes integer), or Integer

  (does not allow the decimal point).

  • The result returned by an alphanumeric function has an implicit usage of DISPLAY. This is why

  the result returned by FUNCTION UPPER-CASE may be used directly with the DISPLAY verb.

  • Intrinsic functions that return a numeric value are always considered to be signed and can

  only be used in an arithmetic expression or a MOVE statement.

  • Intrinsic functions that return a non-integer numeric value can’t be used where an integer

  value is required.

  String Functions

  Table 15-1 lists the intrinsic functions that allow manipulation of strings. The table uses the parameter name to indicate the type of the parameter required, as follows:

  Alpha indicates Alphanumeric.

  Num indicates any Numeric.

  PosNum indicates a positive Numeric.

  Int indicates any Integer.

  PosInt indicates a positive Integer.

  Any indicates that the parameter may be of any type.

  384

  Chapter 15 ■ String Manipulation

  Table 15-1. String Functions, Grouped by Type of Operation

  Function Name

  Result Type

  Comment

  CHAR(PosInt)

  Alphanumeric

  Returns the character in the collating sequence at ordinal position

  PosInt.

  ORD(Alpha)

  Integer

  Returns the ordinal position of character Alpha.

  ORD-MAX({Any}...)

  Integer

  Returns the ordinal position of whichever parameter in the list has

  the highest value. All parameters must be of the same type. The

  parameter list may be replaced by an array. If an array is used, the

  reserved word ALL may be used as the array subscript to indicate

  all the elements of the array.

  ORD-MIN({Any}...)

  Integer

  Returns the ordinal position of whichever parameter in the list

  has the lowest value. All parameters must be of the same type. The

  parameter list may be replaced by an array.

  LENGTH(Any)

  Integer

  Returns the number of characters in the data item Any. Not as

  useful as it sounds. It returns the value given in the item’s picture

  clause. For instance, Length(StrItem) returns 18 if the picture

  clause is PIC X(18).

  REVERSE(Alpha)

  Alphanumeric

  Returns a character string with the characters in Alpha reversed.

  LOWER-CASE(Alpha)

  Alphanumeric

  Returns a character string with the characters in Alpha changed to

  their lowercase equivalents.

  UPPER-CASE(Alpha)

  Alphanumeric

  Returns a character string with the characters in Alpha changed to

  their uppercase equivalents.

  If a function takes a parameter list (indicated by {Any}... in the function definition), the parameter list may be replaced by an array. The reserved word ALL is used as the array subscript to indicate all the elements of the array.

  For instance, the ORD-MAX function may take a parameter list, or you can use an array as the parameter, as shown in the following example:

  MOVE FUNCTION ORD-MAX(12 23 03 78 65) TO OrdPos

  or

  MOVE FUNCTION ORD-MAX(IntElement(ALL)) TO OrdPos

  String Intrinsic Function Examples

  Listing 15-9 solves no specific problem. It merely consists of a number of intrinsic function examples.

  Listing 15-9. String Manipulation with Intrinsic Functions

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing15-9.

  AUTHOR. Michael Coughlan.

  *> Intrinsic Function examples

  385

  Chapter 15 ■ String Manipulation

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 OrdPos PIC 99.

  01 TableValues VALUE "123411457429130938637306851419883522700467".

  02 Num PIC 99 OCCURS 21 TIMES.

  01 idx PIC 9.

  01 xString PIC X(45)

  VALUE "This string is 33 characters long".

  01 xWord PIC X(10).

  01 CharCount PIC 99.

  01 TextLength PIC 99.

  PROCEDURE DIVISION.

  Begin.

  *> eg1. In the ASCII collating sequence W has a code of 87 but an ordinal

  *> position of 88.

&n
bsp; DISPLAY "eg1. The character in position 88 is = " FUNCTION CHAR(88)

  *> eg2. Using ordinal positions to spell out my name

  DISPLAY SPACES

  DISPLAY "eg2. My name is " FUNCTION CHAR(78) FUNCTION CHAR(106)

  FUNCTION CHAR(108) FUNCTION CHAR(102)

  *> eg3. Finding the ordinal position of a particular character

  DISPLAY SPACES

  MOVE FUNCTION ORD("A") TO OrdPos

  DISPLAY "eg3. The ordinal position of A is = " OrdPos

  *> eg4. Using CHAR and ORD in combination to display the sixth letter of the alphabet

  DISPLAY SPACES

  DISPLAY "eg4. The sixth letter of the alphabet is "

  FUNCTION CHAR(FUNCTION ORD("A") + 5)

  *> eg5. Finding the position of the highest value in a list of parameters

  DISPLAY SPACES

  MOVE FUNCTION ORD-MAX("t" "b" "x" "B" "4" "s" "b") TO OrdPos DISPLAY "eg5. Highest character in the list is at pos " OrdPos

  *> eg6. Finding the position of the lowest value in a list of parameters

  DISPLAY SPACES

  MOVE FUNCTION ORD-MIN("t" "b" "x" "B" "4" "s" "b") TO OrdPos DISPLAY "eg6. Lowest character in the list is at pos " OrdPos

  386

  Chapter 15 ■ String Manipulation

  *> eg7.Finding the position of the highest value

  in a table

  DISPLAY SPACES

  MOVE FUNCTION ORD-MAX(Num(ALL)) TO OrdPos

  DISPLAY "eg7. Highest value in the table is at pos "

  OrdPos

  *> eg8. Finding the highest value in a table

  DISPLAY SPACES

  DISPLAY "eg8. Highest value in the table = "

  Num(FUNCTION ORD-MAX(Num(ALL)))

  *> eg9. Finds the top three values in a table by finding the top

  *> overwrites it with zeros to remove it from consideration

  *> then finds the next top and so on

  DISPLAY SPACES

  DISPLAY "eg9."

  PERFORM VARYING idx FROM 1 BY 1 UNTIL idx > 3

  DISPLAY "TopPos " idx " = " Num(FUNCTION ORD-MAX(Num(ALL)))

  MOVE ZEROS TO Num(FUNCTION ORD-MAX(Num(ALL)))

  END-PERFORM

  *> eg10. Finding the length of a string

  DISPLAY SPACES

  DISPLAY "eg10. The length of xString is " FUNCTION LENGTH(xString) " characters"

  *> eg11. Finding the length of the text in a string

  DISPLAY SPACES

  INSPECT FUNCTION REVERSE(xString) TALLYING CharCount

  FOR LEADING SPACES

  COMPUTE TextLength = FUNCTION LENGTH(xString) - CharCount

  DISPLAY "eg11. The length of text in xString is " TextLength " characters"

  *> eg12. Discover if a word is a palindrome

  DISPLAY SPACES

  DISPLAY "eg12."

  MOVE ZEROS TO CharCount

  DISPLAY "Enter a word - " WITH NO ADVANCING

  ACCEPT xWord

  INSPECT FUNCTION REVERSE(xWord)

  TALLYING CharCount FOR LEADING SPACES

  IF FUNCTION UPPER-CASE(xWord(1:FUNCTION LENGTH(xWord) - CharCount)) EQUAL TO

  FUNCTION UPPER-CASE(FUNCTION REVERSE(xWord(1:FUNCTION LENGTH(xWord)- CharCount)))

  DISPLAY xWord " is a palindrome"

  ELSE

  DISPLAY xWord " is not a palindrome"

  END-IF

  STOP RUN.

  387

  Chapter 15 ■ String Manipulation

  Program Explanation

  These examples build on one another so that although the early ones are straightforward, the later ones are somewhat more complex and require explanation. One thing you will realize from these examples is that COBOL’s intrinsic functions are not as effective as functions in other languages. For one thing, the requirement to precede every intrinsic function with the word FUNCTION makes nesting functions cumbersome. For another, the function library is incomplete. You often have to use INSPECT, UNSTRING, and STRING to compensate for omissions. On the other hand, not being able to nest functions deeply may be a good thing. For instance, eg12 would require more typing but would be easier to understand and debug if coded as follows:

  *>eg12. Discover if a word is a palindrome

  DISPLAY SPACES

  DISPLAY "eg12."

  MOVE ZEROS TO CharCount

  DISPLAY "Enter a word - " WITH NO ADVANCING

  ACCEPT xWord

  INSPECT FUNCTION REVERSE(xWord) TALLYING CharCount

  FOR LEADING SPACES

  MOVE FUNCTION UPPER-CASE(xWord) TO xWord

  COMPUTE TextLength = FUNCTION LENGTH(xWord) - CharCount

  IF xWord(1:TextLength) EQUAL TO FUNCTION REVERSE(xWord(1:TextLength))

  DISPLAY xWord " is a palindrome"

  ELSE

  DISPLAY xWord " is not a palindrome"

  END-IF

  Let’s look at how these examples work:

  • eg1 uses the CHAR function to return the eighty-eighth character ( W) of the ASCII collating

  sequence. In most languages, you would be required to supply the ASCII value, whereas in

  COBOL you supply the ordinal position. If you are used to dealing with ASCII values, the

  ordinal position will seem to be off by one: for example, the ASCII value of W is 87.

  • eg2 uses the CHAR function to display the name Mike.

  • eg3 demonstrates that the ORD function is the opposite of CHAR. Whereas CHAR returns the

  character at the ordinal position supplied, ORD returns the ordinal position of the character

  supplied. As you no doubt know, A is ASCII value 65, but its ordinal position is returned as 66.

  • eg4 is the first use of nested functions. CHAR and ORD are used in combination. ORD("A")

  returns the position of the first letter in the alphabet, and the sixth is five letters on from that.

  • eg5 and eg6 demonstrate using the ORD-MAX function to find the position of the highest value

  in the supplied list.

  • eg7 demonstrates how to use ORD-MAX to find the position of the highest value in a table.

  • eg8 uses nesting and ORD-MAX to find the highest value in a table.

  • Eg9 uses the techniques demonstrated in eg7 and eg8 to find the top three values in a table.

  Each time through the loop, the highest value is found, displayed, and then overwritten with

  zeros to remove it from consideration the next time around. This solution does have the

  drawback of destroying some of the values in the table.

  388

  Chapter 15 ■ String Manipulation

  • eg10 and eg11: one problem COBOL has is that alphanumeric data items are fixed in length, so

  if the text does not fill the data item, the data item is space-filled to the right. For certain kinds

  of processing, this is a problem. eg10 shows how to get the length of a data item, and eg11

  shows how to use the length of the data item to get the length of the text in that data item.

  • eg12 brings together much of the material covered in this chapter. The task is to discover

  whether a word entered by the user is a palindrome (reads the same backward as forward). As

  I noted earlier, the nesting of functions makes the program much more difficult to understand.

  This is the algorithm: using the technique of eg11, find the actual length of the word.

  Use reference modification to select only the word from the data item xWord, change it

  to uppercase, and compare it to a reversed, uppercased, version of the word. If they are

  equal, then the word is a palindrome.

  DATE Functions

  Date functions are a homogeneous group of functions that are often very useful. Table 15-2 lists the functions.

  The table uses the same parameter type indicators as Table 15-1 (Alpha, Num, PosNum, Int, PosInt, Any).

  Table 15-2. Date Functions

  Function Name
/>
  Result Type

  Comment

  CURRENT-DATE

  Alphanumeric

  Returns a 21-character string representing the current

  date and time, and the difference between the local time

  and Greenwich Mean Time. The format of the string is

  YYYYMMDDHHMMsshhxhhmm, where YYYY is the year,

  MM is the month, DD is the day of the month, HH is the hour

  (24-hour time), MM is the minutes, ss is the seconds, and

  hh is the hundredths of a second. In addition, xhhmm is the

  number of hours and minutes the local time is ahead of or

  behind GMT ( x = + or - or 0). If x = 0, the hardware cannot

  provide this information.

  DATE-OF-INTEGER(PosInt)

  Integerof the

  Converts the integer date PosInt (representing the number

  form YYYYMMDDD

  of days that have passed since Dec 31, 1600 in the Gregorian

  calendar) to a standard date. Returns the standard date in the

  form YYYYMMDD. This function can be useful when you are

  calculating the number of days between two dates.

  DAY-OF-INTEGER(PosInt)

  Integer of the

  Converts the integer date PosInt(representing the number

  form YYYYDDD

  of days that have passed since Dec 31, 1600 in the Gregorian

  calendar) to a standard date of the form YYYYDDD

  (sometimes called a Julian date).

  INTEGER-OF-DATE(PosInt)

  Integer

  Converts the standard date PosInt (in the form YYYYMMDD)

  into the equivalent integer date. If PosInt is not a valid date,

  then zeros are returned.

  INTEGER-OF-DAY(PosInt)

  Integer

  Converts the standard date PosInt (in the form YYYYDDD—a

  Julian date) into the equivalent integer date.

  WHEN-COMPILED

  Integer

  Returns the date and time the program was compiled. Uses

  the same format as CURRENT-DATE.

 

‹ Prev