Book Read Free

Michael Coughlan

Page 14

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


  88 CityCodeNotValid VALUE 0, 7 THRU 9.

  Table 5-7 shows the Boolean value of the condition names for each value of CityCode.

  86

  Chapter 5 ■ Control StruCtureS: SeleCtion

  Table 5-7. Results for Each Value of CityCode

  Data Item / Condition Name

  Data Value / Condition Name Result

  CityCode

  0

  1

  2

  3

  4

  5

  6

  7 - 9

  CityIsDublin

  False

  TRUE

  False

  False

  False

  False

  False

  False

  CityIsLimerick

  False

  False

  TRUE

  False

  False

  False

  False

  False

  CityIsCork

  False

  False

  False

  TRUE

  False

  False

  False

  False

  CityIsGalway

  False

  False

  False

  False

  TRUE

  False

  False

  False

  CityIsSligo

  False

  False

  False

  False

  False

  TRUE

  False

  False

  CityIsWaterford

  False

  False

  False

  False

  False

  False

  TRUE

  False

  UniversityCity

  False

  TRUE

  TRUE

  TRUE

  TRUE

  False

  False

  False

  CityCodeNotValid

  TRUE

  False

  False

  False

  False

  False

  False

  TRUE

  Values Can Be Alphabetic or Numeric

  The list of values specified for a condition name can be numeric or alphabetic, as shown in Listing 5-3.

  Listing 5-3. Multiple Condition Names with Overlapping Values

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing5-3.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 InputChar PIC X.

  88 Vowel VALUE "A","E","I","O","U".

  88 Consonant VALUE "B" THRU "D", "F","G","H"

  "J" THRU "N", "P" THRU "T"

  "V" THRU "Z".

  88 Digit VALUE "0" THRU "9".

  88 ValidChar VALUE "A" THRU "Z", "0" THRU "9".

  PROCEDURE DIVISION.

  Begin.

  DISPLAY "Enter a character :- " WITH NO ADVANCING

  ACCEPT InputChar

  IF ValidChar

  DISPLAY "Input OK"

  ELSE

  DISPLAY "Invalid character entered"

  END-IF

  IF Vowel

  DISPLAY "Vowel entered"

  END-IF

  IF Digit

  DISPLAY "Digit entered"

  END-IF

  STOP RUN.

  87

  Chapter 5 ■ Control StruCtureS: SeleCtion

  List Values Can Be Whole Words

  Although I have used single characters in the examples so far, condition names are not restricted to values with only single characters. Whole words can be used if required, as shown in Listing 5-4.

  Listing 5-4. Words as Value Items

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing5-4.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 MakeOfCar PIC X(10).

  88 VolksGroup VALUE "skoda", "seat",

  "audi", "volkswagen".

  88 GermanMade VALUE "volkswagen", "audi",

  "mercedes", "bmw",

  "porsche".

  PROCEDURE DIVISION.

  Begin.

  DISPLAY "Enter the make of car - " WITH NO ADVANCING

  ACCEPT MakeOfCar

  IF VolksGroup AND GermanMade

  DISPLAY "Your car is made in Germany by the Volkswagen Group."

  ELSE

  IF VolksGroup

  DISPLAY "Your car is made by the Volkswagen Group."

  END-IF

  IF GermanMade

  DISPLAY "Your car is made in Germany."

  END-IF

  END-IF

  STOP RUN.

  Using Condition Names Correctly

  A condition name should express the true condition being tested. It should not express the test that sets the condition name to true. For instance, in Listing 5-2, a value of 1 in the data item CityCode indicates that the city is Dublin, a value of 2 means the city is Limerick, and so on. These condition names allow you to replace conditions such as IF CityCode = 1

  and

  IF CityCode = 2

  with the more meaningful statements

  IF CityIsDublin

  and

  IF CityIsLimerick.

  88

  Chapter 5 ■ Control StruCtureS: SeleCtion

  Many COBOL beginners would use condition names such as CityCodeIs1 or CityCodeIs2 to express these

  conditions. Those condition names are meaningless because they express the value that makes the condition name true instead of expressing the meaning or significance of CityCode containing a particular value. A value of 1 or 2 in CityCode is how you detect that the city is Dublin or Limerick. It is not the value of CityCode that ultimately interests you; it is the meaning or significance of that value.

  Example Program

  Listing 5-5 is a small but complete program showing how the BritishCountry and CurrencyIsPound condition names might be defined and used. There is something unusual about this example, however. What do you imagine happens to the associated data item when the CurrencyIsPound condition name is set to true?

  Listing 5-5. Detecting BritishCountry and Setting and Using CurrencyIsPound

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing5-5.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 CountryCode PIC 999 VALUE ZEROS.

  88 BritishCountry VALUES 3, 7, 10, 15.

  01 CurrencyCode PIC 99 VALUE ZEROS.

  88 CurrencyIsPound VALUE 14.

  88 CurrencyIsEuro VALUE 03.

  88 CurrencyIsDollar VALUE 28.

  PROCEDURE DIVISION.

  Begin.

  DISPLAY "Enter the country code :- " WITH NO ADVANCING

  ACCEPT CountryCode

  IF BritishCountry THEN

  SET CurrencyIsPound TO TRUE

  END-IF

  IF CurrencyIsPound THEN

  DISPLAY "Pound sterling used in this country"

  ELSE

  DISPLAY "Country does not use sterling"

  END-IF

  STOP RUN.

  89

  Chapter 5 ■ Control StruCtureS: SeleCtion

  Setting a Condition Name to True

  In Listing 5-5, the SET verb is used to set CurrencyIsPound to true. The way condition names normally work is that a value placed into the associated data item automatically sets the condition names that list that value to true. When a condition name is manually set to true using the SET verb, the value listed for that condition name is forced into the associated data item. In Listing 5-5, when the SET verb is used to set CurrencyIsPound to true, the value 14 is forced into CurrencyCode.

  When a condition name that lists more than one value is set to true, the first of the values listed is forced into the associated data item. For instance, if BritishCountry w
ere set to true, then the value 3 would be forced into CountryCode.

  ■ ISO 2002 in standard anS 85 CoBol, the SET verb cannot be used to set a condition name to false. this can be done in iSo 2002 CoBol, but in that case the level 88 entry must be extended to include the phrase

  When Set to FalSe iS literalValue$#

  To set a condition name to true, you use the SET verb. You might think, therefore, that the SET verb is used only for manipulating condition names. But the SET verb is a strange fish. It is used for a variety of unconnected purposes.

  For instance, it is used to set a condition name to true. It is used to increment or decrement an index item. It is used to assign the value of an index to an ordinary data item and vice versa. It is used to set On or Off the switches associated with mnemonic names. In ISO 2002 COBOL, it is used to manipulate pointer variables (yes, ISO 2002 COBOL has pointers) and object references. It is often the target of implementer extensions.

  Because the SET verb has so many different unrelated uses, instead of dealing with it as a single topic I discuss each format as you examine the construct to which it is most closely related.

  SET Verb Metalanguage

  Figure 5-7 shows the metalanguage for the version of the SET verb that is used to set a condition name to true. When the SET verb is used to set a condition name, the first condition value specified after the VALUE clause in the definition is moved to the associated data item. So setting the condition name to true changes the value of the associated data item. This can lead to some interesting data-manipulation opportunities.

  Figure 5-7. Metalanguage for the SET verb condition name version

  In summary, any operation that changes the value of the data item may change the status of the associated

  condition names, and any operation that changes the status of a condition name will change the value of its associated data item.

  SET Verb Examples

  In ANS 85 COBOL, you cannot use the SET verb to set a condition name to false. But you can work around this restriction. Consider Example 5-9. This is more a pattern for processing sequential files than real COBOL code, but it serves to illustrate the point.

  90

  Chapter 5 ■ Control StruCtureS: SeleCtion

  Example 5-9. Setting the EndOfFile Condition Name

  01 EndOfFileFlag PIC 9 VALUE ZERO.

  88 EndOfFile VALUE 1.

  88 NotEndOfFile VALUE 0.

  : : : : : : : :

  READ InFile

  AT END SET EndOfFile TO TRUE

  END-READ

  PERFORM UNTIL EndOfFile

  Process Record

  READ InFile

  AT END SET EndOfFile TO TRUE

  END-READ

  END-PERFORM

  Set NotEndOfFile TO TRUE.

  In this example, the condition name EndOfFile has been set up to flag that the end of the file has been

  reached. You cannot set EndOfFile to false, but you can work around this problem by setting another condition name associated with the same data item to true. When EndOfFile is set to true, 1 is forced into the data item EndOfFileFlag, and this automatically sets NotEndOfFile to false. Similarly, when NotEndOfFile is set to true, 0 is forced into EndOfFileFlag, and this automatically sets EndOfFile to false.

  Design Pattern: Reading a Sequential File

  Because this is your first look at how COBOL processes sequential (as opposed to direct access) files, it might be useful to preview some of the material in Chapter 7 by providing a brief explanation now. The READ verb copies a record (a discrete package of data) from the file on backing storage and places it into an area of memory set up to store it. When the READ attempts to read a record from the file but discovers that the end of the file has been reached, it activates the AT END clause and executes whatever statements follow that clause.

  Example 5-9 shows the pattern you generally use to process a stream of items when you can only discover that you have reached the end of the stream by attempting to read the next item. In this pattern, a loop processes the data in the stream. Outside the loop, you have a read to get the first item in the stream or to discover that the stream is empty. Inside the loop, you have statements to process the stream item and get the next item in the stream.

  Why do you have this strange arrangement? The chief reason is that this arrangement allows you to place the read at the end of the loop body so that as soon as the end of the file is detected, the loop can be terminated. If you used a structure such as

  PERFORM UNTIL EndOfFile

  READ InFile

  AT END SET EndOfFile TO TRUE

  END-READ

  Process Record

  END-PERFORM

  then when the end of file was detected, the program would still attempt to process the nonexistent record.

  Of course, the last valid record would still be in memory, so that last record would be processed twice. Many COBOL

  beginners make this programming error.

  91

  Chapter 5 ■ Control StruCtureS: SeleCtion

  Many beginners attempt to solve this problem by only processing the record if the end of file has not been PERFORM UNTIL EndOfStudentFile

  detected. They use a structure like this:

  DISPLAY StudentName SPACE StudentId SPACE CourseCode

  READ StudentFile

  PERFORM UNTIL EndOfFile

  AT END SET EndOfStudentFile TO TRUE

  READ InFile

  END-READ

  AT END SET EndOfFile TO TRUE

  END-PERFORM

  END-READ

  CLOSE StudentFile

  IF NOT EndOfFile

  STOP RUN.

  Process Record

  END-IF

  In Listing 5-6, the condition name EndOfStudentFile is associated with the group item (which also happens to END-PERFORM

  be a record) StudentDetails. When EndOfStudentFile is set to true, the entire StudentDetails area of storage (38 characters) is flushed with highest possible character value.

  The problem with this arrangement is that the IF statement will be executed for every record in the file. Because This arrangement has two major advantages:

  COBOL often deals with very large data sets, this could amount to the execution of millions, maybe even hundreds

  •

  of millions, of unnecessary statements. It is more elegant and more efficient to use what is called the read-ahead The EndOfStudentFile condition name is kept with its associated file.

  technique. The read-ahead has a read outside the loop to get the first record and a read inside the loop to get the

  • Flushing the record with HIGH-VALUES at the end of the file eliminates the need for an explicit

  remaining records. This approach has the added advantage of allowing the empty file condition to be detected before condition when doing a key-matching update of a sequential file.

  the loop is entered.

  Group Item Condition Names

  Condition Name Tricks

  In Example 5-9, stand-alone condition names were used to flag the end-of-file condition. Because the EndOfFile When you become aware that setting a condition name forces a value into the associated data item, it is tempting to condition name is closely related to the file, it would be better if the declaration of the condition name were kept with see just how far you can take this idea. Listing 5-7 takes advantage of the way condition names work to automatically the file declaration. The example program in Listing 5-6 shows how that might be done. It also demonstrates how a move an appropriate error message into a message buffer. The program is just a stub to test this error-messaging idea; condition name can be used with a group (as opposed to elementary) data item.

  it doesn’t actually validate the date. Instead, the user manually enters one of the codes that would be returned by the date-validation routine.

  Listing 5-6. Reading a File and Setting the EndOfStudentFile Condition Name

  Listing 5-7. Using Condition Names to Se
t Up a Date-Validation Error Message

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing5-6.

  IDENTIFICATION DIVISION.

  AUTHOR. Michael Coughlan.

  PROGRAM-ID. Listing5-7.

  ENVIRONMENT DIVISION.

  AUTHOR. Michael Coughlan.

  INPUT-OUTPUT SECTION.

  FILE-CONTROL.

  DATA DIVISION.

  SELECT StudentFile ASSIGN TO "Listing5-6-TData.Dat"

  WORKING-STORAGE SECTION.

  ORGANIZATION IS LINE SEQUENTIAL.

  01 ValidationReturnCode PIC 9.

  88 DateIsOK VALUE 0.

  DATA DIVISION.

  88 DateIsInvalid VALUE 1 THRU 8.

  FILE SECTION.

  88 ValidCodeSupplied VALUE 0 THRU 8.

  FD StudentFile.

  01 StudentDetails.

  01 DateErrorMessage PIC X(35) VALUE SPACES.

  88 EndOfStudentFile VALUE HIGH-VALUES.

  88 DateNotNumeric VALUE "Error - The date must be numeric".

  02 StudentId PIC X(8).

  88 YearIsZero VALUE "Error - The year cannot be zero".

  02 StudentName PIC X(25).

  88 MonthIsZero VALUE "Error - The month cannot be zero".

  02 CourseCode PIC X(5).

  88 DayIsZero VALUE "Error - The day cannot be zero".

  88 YearPassed VALUE "Error - Year has already passed".

  PROCEDURE DIVISION.

  88 MonthTooBig VALUE "Error - Month is greater than 12".

  Begin.

  88 DayTooBig VALUE "Error - Day greater than 31".

  OPEN INPUT StudentFile

  88 TooBigForMonth VALUE "Error - Day too big for this month".

  READ StudentFile

  AT END SET EndOfStudentFile TO TRUE

  END-READ

  92

  Chapter 5 ■ Control StruCtureS: SeleCtion

 

‹ Prev