11 March 2003
IT52/IS22 COBOL 1
11 March 2003 IT52/IS22 COBOL 1
The Unit
• Delivered as IT52/IS22• Lecturing by Richard Bland, practical support from Mr WS
Johnstone• Unit co-ordinator: Richard Bland• Email addresses etc are on the syllabus sheet• Course materials will be placed on the WWW at appropriate
times as the unit proceeds
11 March 2003 IT52/IS22 COBOL 2
Teaching, Assessment, Textbook
• Daytime teaching– 3 lectures per week, times on syllabus sheet– 1 Practical session per week in 1A11 (starts week 3)– 1 Tutorial per week (starts week 3)– IT PGs have been allocated to groups, ISMs should see me
• Assessment– A COBOL assignment (40%) and an exam (60%)– Assignment date 3rd April
• Parkin, A. & Yorke COBOL for Students, 4th edition, EdwardArnold, 1995
– or any other text based on the 85 standard– if you buy MicroFocus COBOL (as used in this unit) for
your own machine, you get a reference manual as well
11 March 2003
IT52/IS22 COBOL 2
11 March 2003 IT52/IS22 COBOL 3
COBOL
• COBOL: COmmon Business-Oriented Language– a language designed for commercial data processing
• That is: handling large amounts of data, normally a large numberof “records” with a regular structure
• “regular structure”: data are in fixed “fields” in the records:123456789012345678901234567890 ..Mr R Bland 7424Mr CMIRattray 7429
– we talk about “the surname field” occupying “columns 8-27”• COBOL is a language specifically designed for processing
fixed-format data with great speed and a high level of control– accuracy, robustness, and control are very important
11 March 2003 IT52/IS22 COBOL 4
Some COBOL History
• COBOL is one of the oldest “third generation” languages• It was developed in 1959 to replace machine code dependent
assemblers (about same time as FORTRAN)• CODASYL committee: COnference on Data System Languages.• Made up from Government agency reps• Grace Hopper, who was on the committee, was the “mother” of
COBOL (and, on one version of the story, coined “bug”)• First ANSI (American National Standards Institute) version was
COBOL 68, although it had been commonly used since 61• COBOL became very popular in business. Led to 74, and 85
standards. The vast majority of COBOL programs in existencetoday follow the 85 standard
11 March 2003
IT52/IS22 COBOL 3
11 March 2003 IT52/IS22 COBOL 5
Status Now
• 100+ billion of lines of COBOL exist today• The is a considerable demand for COBOL programmers to work
on “legacy systems”• (and in 1999 there was particular interest in ones that stored the
year in two digits ..)• A great deal of development is still done in COBOL
– 5 billion lines of code per year?• Several companies make version for PCs, UNIX, and other
operating systems.• Still the choice for a business oriented language• The new standard ("2002+") contains proposals for OO features:
but we shall focus on classic COBOL
11 March 2003 IT52/IS22 COBOL 6
COBOL 85 compared with the ALGOL family
• No block structure: all variables global• Procedures ("Methods") are parameterless (unless externally
linked)• Weaker typing• Numbers: much closer to human arithmetic
– stress on length of number– numbers decimal not floating-point
• I/O record oriented not stream oriented• No recursion• “Bigger” (because facilities not packaged as libraries)
11 March 2003
IT52/IS22 COBOL 4
11 March 2003 IT52/IS22 COBOL 7
Programming in COBOL compared with Java
• There are a number of differences in the paradigm– a new way of thinking is required (not OO)
• COBOL is closer to the machine• In terms of data:
– before the steps of the program, we reserve all the memorythat we shall need (instead of asking for new objectsdynamically)
– we think of memory as contiguous bytes (instead of hardlythinking of memory at all)
• In terms of program flow:– instead of an implied loop through events (e.g. waiting for a
mouse click), we explicitly program a loop through the inputdata
11 March 2003 IT52/IS22 COBOL 8
The COBOL that we shall use
• We shall use the MicroFocus Personal COBOL for Windows,running on the machines in 1A11 and CS labs
• This offers an environment (“Animator”) in which the programcan be edited and tested
• Notice that we shall not be producing executables, but MF .intfiles
– these can be run by Animator– or by special MF shells (RunW and RunFront)
• Personal COBOL offers features that we shall not be using– Facilities to build programs that use the Windows GUI– OO facilities that anticipate the forthcoming standard
• So we shall restrict ourselves to COBOL 85, with terminal i/o ina plain text window
11 March 2003
IT52/IS22 COBOL 5
11 March 2003 IT52/IS22 COBOL 9
An aside: The set-up of your environment
• The names of files in the MS enviroments (MS-DOS, Windows3.1, 95, 98, NT) usually end with a dot and three characters: theextension)
• Windows allows you to hide these: but some people think that itis better to be able to see the extensions
– you set this using the options under View in an Explorerwindow (next slide)
• Each extension can be “associated” with one application– for example, .ppt is usually associated with MS
PowerPoint
• If there is an association– the file displays the icon of the application– and that application starts when the icon is double-clicked
11 March 2003 IT52/IS22 COBOL 10
Aside continued: File extensions
• (It is easy to be confused by this,and think that a file with a .pptextension “is a PowerPoint file”
– it should be, but isn’tnecessarily)
• The lab machines are set up thus:– .cbl is associated with
Animator– .int is associated with RunW
• So you ought to see appropriatebehaviour when you double-clicktheir icons
11 March 2003
IT52/IS22 COBOL 6
11 March 2003 IT52/IS22 COBOL 11
Hello, world
• Here’s a complete COBOL program:
* This is a demonstration program* PROCEDURE DIVISION. DISPLAY "Hello, world" STOP RUN.
– (we shall see later that each line starts with six blanks)• We could either:
– Put this text in a plain ASCII file called (say) hello.cbl(using any simple text editor, such as Notepad) and thendouble-click the file’s icon to bring up Animator
– Bring up Animator from the Start button, and type in the textdirectly, then save the file from Animator
• Let us try some of that:
11 March 2003 IT52/IS22 COBOL 12
Hello, world in Animator
• We can compile the program (using the button with a tick on it,or through the Compile/Run menu)
– if there are errors, we can edit and recompile (Animator willalways save an altered file before recompilation)
• If Animator is open in Edit+Execute mode, then we can run theprogram: otherwise we close, & reopen the file in Execute mode
11 March 2003
IT52/IS22 COBOL 7
11 March 2003 IT52/IS22 COBOL 13
Hello, world (continued)
• Animator puts the output into a plain black window– to see it, you may need to cycle round the windows using alt-
tab• We can step or free-run• And we can set breakpoints• We shall see later that we can inspect the values of variables as a
run proceeds
11 March 2003 IT52/IS22 COBOL 14
Layout of lines of code
• Before we look at the specific features of hello, a note aboutthe layout of a 74 standard program
– COBOL programs were typically entered on punched cards(one program line = one punched card). It was a catastropheif the deck got dropped, and so the cards had sequence-numbers punched on them in columns 1-6. (A dropped deckcould then be restored using a counter-sorter.)
– Column 7 was the indicator-area: '*' for a comment, '-' for acontinuation line (with e.g. a long text constant split acrossthe continuation)
– Columns 8-11 was Area A, where division, section andparagraph names had to start (and some level numbers,discussed later)
– Columns 12-72 were for everything else in the code– Columns 73-80 were alternative locations for card-numbers
11 March 2003
IT52/IS22 COBOL 8
11 March 2003 IT52/IS22 COBOL 15
Layout of lines of code (continued)
• When disks got big and cheap enough, programs were held ondisk and the need for the above format disappeared
– non-standard formats appeared• However, Animator preserves the special nature of columns 1-7
and 73-80• I shall (try to) show program examples with the first six
characters omitted, and using Area A and Area B conventionally
11 March 2003 IT52/IS22 COBOL 16
Hello, world (continued)
• Some more points about the program text– The full-stops are significant. And double-quotes (not single
quotes) in a standard-conforming program.– We see two statements and one sentence. The full-stop
terminates a sentence.– What terminates a statement?
– Not newline (can be split across lines)– Can be some explicit terminator (full-stop, END-something) ...– or the start of a new statement
– Comma and semicolon followed by space are equivalent tospace. This can be put to good or bad effectADD bonus overtime TO payADD bonus, overtime TO pay
DISPLAY ; "Hello World", , STOP ; RUN.
11 March 2003
IT52/IS22 COBOL 9
11 March 2003 IT52/IS22 COBOL 17
Hello, world (continued)
• Yet more points about the program text– Sentences can be grouped into (named) paragraphs (later).
(Our Procedure Division, above, has a single anonymousparagraph.)
– Paragraphs into (named) sections (later)– then divisions. Here we see the Procedure Division. This is
always present. In a program conforming to the 74 standard,all four divisions must be present.
11 March 2003 IT52/IS22 COBOL 18
COBOL: That is data processing - I.E. D.P.
* This is a demonstration program* IDENTIFICATION DIVISION.* (This division could be replaced by comments) PROGRAM-ID. Hello. AUTHOR. Richard Bland. DATE-WRITTEN. February 3rd 2003. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. Viglen-Genie. OBJECT-COMPUTER. Viglen-Genie. DATA DIVISION. PROCEDURE DIVISION. DISPLAY "Hello, world" STOP RUN.
– This has an empty Data Division because the program has novariables. However ...
11 March 2003
IT52/IS22 COBOL 10
11 March 2003 IT52/IS22 COBOL 19
Answer, Echo, Answer
IDENTIFICATION DIVISION. PROGRAM-ID. Echo. AUTHOR. Richard Bland. DATE-WRITTEN. February 3rd 2003. ENVIRONMENT DIVISION.* DATA DIVISION. WORKING-STORAGE SECTION. 77 x PIC 999.* PROCEDURE DIVISION. DISPLAY "Please enter a number" ACCEPT x DISPLAY "That number was ", x STOP RUN.
• We see that a variable is declared and used• We can get Animator to show its current value
11 March 2003 IT52/IS22 COBOL 20
An echo from the East Indies// Read a number from the keyboard and echo it//import java.io.*;
public class Echo { public static void main(String[] args) { String line ; int x ; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ; System.out.print("Please enter a number:") ; try { line = br.readLine() ; x = Integer.parseInt(line) ; System.out.println("That was " + x) ; } catch (Exception e) {System.out.println(e.getMessage()) ; } } // main} // class
11 March 2003
IT52/IS22 COBOL 11
11 March 2003 IT52/IS22 COBOL 21
Echo: syntax
• The statements in the Procedure Division are typical: theyconsist of (imperative) verbs followed by (mainly) nouns andprepositions
FEED catPUT canary INTO cage.
• We can use syntax formats or diagrams to describe all parts ofCOBOL. In these notes I’ll use formats, as in (e.g.) Appendix Dof Parkin and Yorke. I’ll use italic for these
ACCEPT ident [FROM name]
• Caps for words to be entered as-is, l/c for an element to bereplaced
ACCEPT x
11 March 2003 IT52/IS22 COBOL 22
Syntax (continued)
• Square brackets enclose optional parts ACCEPT x FROM DAY-OF-WEEK* Integer from 1 (Mon) to 7, returned by system
• Underline indicates that word must be present if element is used.DISPLAY { ident | literal} ... [WITH NOADVANCING]
DISPLAY "Enter a number" NO ADVANCING
• Curly brackets with a vertical bar indicate a choiceDISPLAY xDISPLAY 42DISPLAY "Goodbye"
• Three dots (ellipsis) indicate that the previous element can berepeated as often as you like
DISPLAY "The number was" x ", was it not?"
11 March 2003
IT52/IS22 COBOL 12
11 March 2003 IT52/IS22 COBOL 23
Declaring variables
• Let us now turn to the Data Division of echoDATA DIVISION.WORKING-STORAGE SECTION.77 x PIC 999.
• Before the detail, let's look at the big picture. The Data Divisionof any COBOL program can consist of three Sections: File,Working-Storage and Linkage. We shall not deal with the last.The first two relate to COBOL's model of data movement.
11 March 2003 IT52/IS22 COBOL 24
COBOL's data model
• Parkin Figure E1
Input File Output File
File Section
Input Record Output Record
Working-Storage Section
READ WRITE
Data Division
11 March 2003
IT52/IS22 COBOL 13
11 March 2003 IT52/IS22 COBOL 25
COBOL's data model (continued)
• In the echo program we used the low-volume verbs ACCEPTand DISPLAY, used for terminal I/O
• The high-volume, file-related verbs are READ and WRITE• In the general case, data movement is as follows:
– Input data are transferred to an input area which isessentially a map of the input record.
– Output data are similarly written from an area which is amap of the desired output record.
– The output area is built up in two ways: by moving datafrom the input directly; and by moving data to working-storage, transforming it and moving it to the output area
• We shall see examples later on. In the case of the presentexample, we had no File Section because we had no files.
11 March 2003 IT52/IS22 COBOL 26
Returning to echo's Data Division
DATA DIVISION.WORKING-STORAGE SECTION.77 x PIC 999.
• This says that we are declaring a variable x. It is "at level 77":which means that it has no internal structure and no definedrelationship to any other variable. The PIC clause shows that itis numeric, integer, and can hold numbers 0-999. It occupies 3locations in memory.
• If we experiment:4 That number was 00442 That number was 04241. That number was 041424 That number was 424
• It is not always easy to grasp what ACCEPT/DISPLAY are doing.But a guess that three digits were being stored would be correct.
11 March 2003
IT52/IS22 COBOL 14
11 March 2003 IT52/IS22 COBOL 27
An Aside about ACCEPT
• With MF (but not all COBOLs), ACCEPT into a numeric alwaysproduces a numeric. Consider the echo program:
Keyed Value Stored123 12312 0121 001
– so far so good. But:12X 0121XY 001ZXY 000
• This behaviour is defensible, but not much help if you want tocheck user input. One possible solution involves constructs thatwe shall cover later. For the moment, concentrate on dealingwith genuinely-numeric input.
11 March 2003 IT52/IS22 COBOL 28
First look at the PIC clause: decimal fractions
• If we were using READ the system would expect three digits(possibly with leading blanks)
• In order to handle decimal points:DATA DIVISION.WORKING-STORAGE SECTION.77 x PIC 99V9.
• This means that a decimal point is implied at the indicatedposition. It is not held in the variable: and indeed it does notappear on the output.
42 That number was 4204.9 That number was 049
• We shall see later how to edit to obtain less brutal output.
11 March 2003
IT52/IS22 COBOL 15
11 March 2003 IT52/IS22 COBOL 29
First look at the PIC clause: signed numbers
• How about a sign?77 x PIC S999.
• In this case the sign is stored in the same locations as the digits(in an implementation-dependent way)
• There is an optional phrase:[[SIGN IS] { LEADING | TRAILING } [SEPARATECHARACTER]]
• So we can write77 x PIC S999 SIGN IS LEADING SEPARATE.
now the number is stored in four locations• Instead of (e.g.) 9999999 we can write 9(7)
11 March 2003 IT52/IS22 COBOL 30
First look at the PIC clause: alphabetic and alphanumeric
• We have been looking at “simple” PIC clauses (as opposed toedited ones, later). There are three types: numeric (as above),and
• alphabetic ('A' - 'Z' and 'a' - 'z')PIC AAAAAPIC A(5)
• alphanumeric (any characters)PIC XXXXXPIC X(5)
11 March 2003
IT52/IS22 COBOL 16
11 March 2003 IT52/IS22 COBOL 31
Name-formation and constants
• We called our variable 'x'. In fact we can use up to 30characters, using letters, digits, and hyphen (not first or last)
Pay-RatepayratePayRateDay-7
watch out for the reserved words! (Count)• Alpha constants in double-quotes.• There are symbolic constants (“figurative constants”)
ZERO ZEROS ZEROES SPACE SPACESHIGH-VALUE LOW-VALUE
– so the following are equivalent:MOVE 0 TO I
MOVE ZERO TO I
11 March 2003 IT52/IS22 COBOL 32
Constants continued, and VALUE
orMOVE " " TO NAME
MOVE SPACES TO NAME
• In Working-storage only, we can declare-and-initialise77 x PIC 999 VALUE IS ZERO.
77 Vat-Rate PIC 99V9 VALUE IS 17.5 .
• Question: why is it only in Working-storage that we can declare-and-initialise?
11 March 2003
IT52/IS22 COBOL 17
11 March 2003 IT52/IS22 COBOL 33
More verbs
• We shall return to data-declaration and data-structures, but forthe next few slides we look at some new Procedure Divisionverbs
• The arithmetic verbs: we start with ADD (and spend quite a longtime on it)
• We can have ADD-TO and ADD-GIVINGADD { ident | literal } ... TO {ident [ROUNDED]} ...
– ident is a variable-name, literal is a constant– where does the result go??
ADD 1 TO KountADD Vat TO PriceADD Vat, Delivery TO PriceADD 1 TO Kount, Stack-PtrADD Vat TO Price ROUNDED
11 March 2003 IT52/IS22 COBOL 34
ADD (continued)
– rounding is to the number of decimal places specified in thePIC of the result. 5 and over rounds up.
• The ADD-GIVING version isADD {ident | literal} ... GIVING {ident [ROUNDED]} ...
• (We can have an optional TO before the final input operand. Ihave omitted this in the syntax.)
• In both cases, the ellipsis in the result comes after the optionalROUNDED. So we can construct a total in number of differentways: to different precisions and with/without rounding
ADD x,y,z GIVING Int-Ans ROUNDED, Real-Ans
• Let's write a complete program:
11 March 2003
IT52/IS22 COBOL 18
11 March 2003 IT52/IS22 COBOL 35
A complete ADD example
* Addition* DATA DIVISION. WORKING-STORAGE SECTION. 77 a PIC 99V999 VALUE 1.777 . 77 b PIC 99V99 VALUE ZERO . 77 c PIC 9V9 VALUE 5.5 . 77 d PIC 9V9 VALUE 5.5 . PROCEDURE DIVISION. ADD a TO b ROUNDED DISPLAY "b is ", b ADD c TO d DISPLAY "d is ", d STOP RUN.
11 March 2003 IT52/IS22 COBOL 36
What the example does
• The output isb is 0178d is 10
• The value for b is correct, but something nasty has happened tod. What is the problem?
• It is this:– the numbers to be added are aligned on their decimal points– added– and then moved to the result variable– which in this case is too small
• In fact the syntax is more complicated: in both cases we canhave SIZE ERROR clauses
11 March 2003
IT52/IS22 COBOL 19
11 March 2003 IT52/IS22 COBOL 37
SIZE ERROR clauses
ADD { ident | literal } ... TO {ident [ROUNDED]} ... [ON SIZE ERROR imperative-statement] [NOT ON SIZE ERROR imperative-statement] [END-ADD]
– imperative-statement can be several statements– To terminate this series of statements we use either full-stop
(74) or END-ADD (85).– Let us first program on the assumption that any size error
should stop the program:
11 March 2003 IT52/IS22 COBOL 38
Add example (continued)
PROCEDURE DIVISION. ADD a TO b ROUNDED ON SIZE ERROR DISPLAY "Size Error" ; STOP RUN END-ADD DISPLAY "b is ", b ADD c TO d ON SIZE ERROR DISPLAY "Size Error" ; STOP RUN END-ADD DISPLAY "d is ", d STOP RUN.
• The output isb is 0178Size Error
11 March 2003
IT52/IS22 COBOL 20
11 March 2003 IT52/IS22 COBOL 39
ADD example in 74 style
• The 74 style with full-stops is a bit more succinct.PROCEDURE DIVISION. ADD a TO b ROUNDED ON SIZE ERROR DISPLAY "Size Error" ; STOP RUN. DISPLAY "b is ", b ADD c TO d ON SIZE ERROR DISPLAY "Size Error" ; STOP RUN. DISPLAY "d is ", d STOP RUN.
• We could also anticipate later material about program structure(“performing a paragraph”):
11 March 2003 IT52/IS22 COBOL 40
ADD example using PERFORM
PROCEDURE DIVISION.Main-para. ADD a TO b ROUNDED ON SIZE ERROR PERFORM Add-Error. DISPLAY "b is ", b ADD c TO d ON SIZE ERROR PERFORM Add-Error. DISPLAY "d is ", d STOP RUN.Add-Error. DISPLAY "Size Error" ; STOP RUN.
• This example introduces– paragraph-names (note full-stops)– the idea that we can ask for a paragraph to be PERFORMed:
that is, control passes to the code in the paragraph
11 March 2003
IT52/IS22 COBOL 21
11 March 2003 IT52/IS22 COBOL 41
The ADD example using NOT
• Alternatively we could program so that any size-error is non-fatal
PROCEDURE DIVISION. ADD a TO b ROUNDED ON SIZE ERROR DISPLAY "Size Error" NOT SIZE ERROR DISPLAY "b is ", b END-ADD ADD c TO d ON SIZE ERROR DISPLAY "Size Error" NOT SIZE ERROR DISPLAY "d is ", d END-ADD STOP RUN.
• There's no absolute "best way": it depends on circumstances.
11 March 2003 IT52/IS22 COBOL 42
Defensive programming
• Should we always test for size errors?DATA DIVISION.WORKING-STORAGE SECTION.77 c PIC 9V9 .77 d PIC 9V9 .77 e PIC 99V9 .PROCEDURE DIVISION. ... ADD c, d GIVING e
• This can never have a size error• - but suppose a later change alters the PICs of the input variables• A sense of proportion must be kept: but bitter experience teaches
us the value of testing for “impossible” errors– “Can’t happen” messages
11 March 2003
IT52/IS22 COBOL 22
11 March 2003 IT52/IS22 COBOL 43
SUBTRACT
• Subtract is very similar. First, the version without GIVINGSUBTRACT { ident | literal} ... FROM {ident [ROUNDED]} ...
– The total of the values on the left is subtracted from each ofthe variables on the rightSUBTRACT Tax, Insurance, Sports, Union FROM Pay
SUBTRACT 1 FROM Loop1, Loop2
• Then the version with GIVINGSUBTRACT { ident | literal} ... FROM { ident | literal} GIVING {ident [ROUNDED]} ...
– The total of the values on the left is subtracted from a singlevalue, and the result is stored, possibly in several variables
11 March 2003 IT52/IS22 COBOL 44
SUBTRACT (continued)
SUBTRACT a, b, c FROM 100 GIVING d
• Notice that with ADD-GIVING the TO was optional, but withSUBTRACT-GIVING the FROM is compulsory
• Rounding can be used as with ADD• We can also have the same size error clauses, and can terminate
the statement with END-SUBTRACT in the same style as withADD
• But do we need size error clauses? Surely subtracting somethingalways gives you a result smaller than the value you startedwith?
11 March 2003
IT52/IS22 COBOL 23
11 March 2003 IT52/IS22 COBOL 45
MULTIPLY
• Versions with and without GIVINGMULTIPLY {ident | literal} BY {ident [ROUNDED]} ...
– A single value on the left is used to multiply each of anumber of variables on the rightMULTIPLY {ident | literal} BY {ident | literal} GIVING {ident [ROUNDED]} ...
– Two values are multiplied together and the result is stored,possibly in several variablesMULTIPLY x BY y GIVING z ROUNDED, w
• We can have size error clauses and END-MULTIPLY
11 March 2003 IT52/IS22 COBOL 46
DIVIDE
DIVIDE {ident | literal} INTO {ident [ROUNDED]} ...
• A single value on the left is divided-into each of a number ofvariables on the right
DIVIDE {ident | literal} INTO {ident | literal} GIVING {ident [ROUNDED]} ...
• A value is divided into another value and the result is stored,possibly in several variables.
DIVIDE 2 INTO x GIVING y, z
• We can write this the other way round using BYDIVIDE x BY 2 GIVING y, z
• Can have size error clauses and END-DIVIDE (and REMAINDER)
11 March 2003
IT52/IS22 COBOL 24
11 March 2003 IT52/IS22 COBOL 47
Some of these are wrong
MULTIPLY Salary BY 2
MUTLIPLY Salary BY 2 GIVING Delirium, Ecstasy
MULTIPLY 2 BY Salary
DIVIDE Cake INTO 5
DIVIDE 3 INTO Gaul
ADD 5, 6, 8, 3, 7, 4, 5, 4, 7 GIVING Outward
SUBTRACT 1, 2, 1, 1, 2, 1, 2, 1, 1 FROM Outward GIVING Handicapped
MULTIPLY x ROUNDED BY y
MULTIPLY x BY y ROUNDED
ADD Mark-up AND Tax TO Net GIVING Gross
11 March 2003 IT52/IS22 COBOL 48
COMPUTE
COMPUTE { ident [ROUNDED] } ... = arithmetic-expression
– with possible size error clauses and END-COMPUTE• the arithmetic expression is constructed using the usual operators
(** to raise to a power) and brackets• strictly, a space on either side of each operator: usually the
compiler only enforces this for minus (why?)• evaluation follows the usual precedence and left-to-right rules
COMPUTE Celsius = (Fahrenheit - 32) / 1.8
COMPUTE Area = 3.1416 * Radius ** 2
• some programmers feel it is safer to carry out the calculation instages
11 March 2003
IT52/IS22 COBOL 25
11 March 2003 IT52/IS22 COBOL 49
Transfer of control: IF
IF Tax > 100 THEN DISPLAY "Surely not"ELSE DISPLAY "Oh, all right" END-IF
• We shall look at conditions soon.• The word THEN is optional, as is the ELSE part: and END-IF
was introduced in the 85 Standard as an optionIF Tax > 100 DISPLAY "Rats" .
• But the use of END-IF is strongly recommended. (The full-stopcloses all open IFs and so some nested constructions cannot becoded in a natural way if it is used)
11 March 2003 IT52/IS22 COBOL 50
IF (continued)
• Each branch can contain a sequence of statements. (But,obviously, no full-stops)
• (The old NEXT SENTENCE construct is unnecessary post-85)• Obviously, we should adopt some sensible indentation
convention (such as two spaces)• We can nest Ifs
IF c1 THEN IF c2 THEN s1 ELSE s2 END-IFELSE s3 END-IF
11 March 2003
IT52/IS22 COBOL 26
11 March 2003 IT52/IS22 COBOL 51
Matching ELSE with its IF
• In that example, we could omit the END-IFsIF c1 THEN IF c1 THEN IF c2 THEN IF c2 THEN s1 s1 ELSE ELSE s2 s2 END-IF ELSEELSE s3 . s3 END-IF
• The version on the right has the same effect and is shorter...• This temptation should be firmly resisted. Consider the
example on the next slide
11 March 2003 IT52/IS22 COBOL 52
Catastrophe caused by omitting inner END-IF
• The indentation suggests that the programmer thinks that thesetwo fragments are equivalent: but (s)he is wrong
IF c1 THEN IF c1 THEN IF c2 THEN IF c2 THEN s1 s1 END-IF ELSEELSE s2 . s2 END-IF
• The ELSE is matched with the closest un-elsed IF.• Moral: always put in the END-IFs• (Note: for the equivalent of a C or Java switch (Pascal CASE)
see EVALUATE on Slide 174)
11 March 2003
IT52/IS22 COBOL 27
11 March 2003 IT52/IS22 COBOL 53
Transfer of control: Out-of-line PERFORM
• Using PERFORM is a bit like using a Java methodPROCEDURE DIVISION.Main-para. PERFORM Greeting PERFORM Doit PERFORM Sign-Off STOP RUN.Doit. DISPLAY "Please enter a number" ACCEPT x DISPLAY "That number was " x .Greeting. DISPLAY "Hello".Sign-off. DISPLAY "Goodbye".
• The blocks of code are terminated by full-stop-followed-by-new-paragraph-name (or by end of program text)
11 March 2003 IT52/IS22 COBOL 54
Out-of-line PERFORM, continued
• When the flow of control encounters PERFORM– control passes to the paragraph to be performed (like a jump)– but the system remembers where we jumped from– and at the end of the paragraph we jump back to the
statement after the PERFORM• So the example on the previous slide is equivalent to
PROCEDURE DIVISION. DISPLAY "Hello". DISPLAY "Please enter a number" ACCEPT x DISPLAY "That number was " x . DISPLAY "Goodbye". STOP RUN.
Greeting
Doit
Sign-off
11 March 2003
IT52/IS22 COBOL 28
11 March 2003 IT52/IS22 COBOL 55
Benefits of out-of-line PERFORM
• The example on the last two slides shows (in a trivial example)how we can obtain clarity by moving details into subsidiaryparagraphs
• The first paragraph then corresponds to a top-level description ofthe algorithm. We refer to this as the “main paragraph”
– for example, many programs have a three-phase structure:initialise, process, tidy-up
* This is the Procedure Division's first para Main-para. PERFORM Start-up PERFORM Process-data PERFORM Tidy-up STOP RUN.* The code for the three paragraphs follows
11 March 2003 IT52/IS22 COBOL 56
Global variables
• However, procedures / functions / methods in Pascal / C / Java /Fortran can have private variables
• and we can pass parameters to them, applying them to particularobjects
// draw circle at (10,10), radius 2mycircle.draw(10,10,2) ;
• In COBOL, on the other hand, all paragraphs share the samevariables. All variables are “global”
• Instead of passing parameters, we initialise the variables that weknow that the paragraph will use, and perform the paragraph.On return, we use the variables as modified by the paragraph
• There should always be comments at the top of each paragraphto say what variables are used and which are changed
11 March 2003
IT52/IS22 COBOL 29
11 March 2003 IT52/IS22 COBOL 57
Out-of-line PERFORM (continued)
• On Slide 54, the paragraphs were in an order that showed thatcontrol does not simply fall through from paragraph to paragraph
• Here’s an extension of PERFORMPROCEDURE DIVISION.Main-para. PERFORM Greeting THROUGH Sign-off. STOP RUN.Greeting. DISPLAY "Hello".Doit. DISPLAY "Please enter a number" . ACCEPT x . DISPLAY "That number was " x .Sign-off. DISPLAY "Goodbye".
• We can spell THROUGH as THRU
11 March 2003 IT52/IS22 COBOL 58
Order of execution of COBOL paragraphs
• In C, Java, Pascal, Fortran (etc) the only way of entering aprocedure/function/method is by an explicit call
– and whenever we leave it, we return to the point after the call• In COBOL, too, we can PERFORM a paragraph, in which case
– when we get to the end of the called paragraph we return tothe point after the call
• But in COBOL we can also execute a paragraph just by fallingoff the end of the paragraph before, in which case we don'treturn anywhere: we just fall into the next paragraph
• The next slide has an unlikely but possible arrangement thatillustrates these two possibilities
11 March 2003
IT52/IS22 COBOL 30
11 March 2003 IT52/IS22 COBOL 59
Order of execution (continued)
PROCEDURE DIVISION.Main-para. DISPLAY "Main-para".A. DISPLAY "A".B. DISPLAY "B1" PERFORM A DISPLAY "B2".
• What is the order of execution?• So: we executed paragraph A twice
– the first time we fell into it (and so we fell out of it when itwas finished)
– the second time we jumped into it with PERFORM (and so wejumped back when it was finished).
11 March 2003 IT52/IS22 COBOL 60
Order of execution: STOP
• Programs don’t always need STOP– because they will stop anyway if they are about to go past
the last line– so we only need as explicit STOP if the program is meant to
stop at some earlier point– as in, say, Slide 54
• But STOP is normally a useful visual clue. We might expect tofind it at the end of a “main-para” or a “closedown” para
11 March 2003
IT52/IS22 COBOL 31
11 March 2003 IT52/IS22 COBOL 61
Nested Out-of-line PERFORMS
• Of course, the code executed as a result of a PERFORM may itselfcontain PERFORM.
Main-para. Main-para. ... ... PERFORM A PERFORM A THRU C STOP RUN. STOP RUN.A. A. ... ... PERFORM B PERFORM B ... ...B. B. ... ... C. ...
• These are nested PERFORMs– while PERFORMing A, we PERFORM B
11 March 2003 IT52/IS22 COBOL 62
Nested Out-of-line PERFORMS (continued)
• We say that the range of a PERFORM is all the statementsexecuted as the result of the PERFORM.
• The rule for nesting: the range of the inner must lie entirelyoutside the range of the outer (left-hand example) or entirelywithin it (right-hand example)
• The ranges must not overlap, or share the same end point.• (MF COBOL does not enforce this rule, and it even allows
recursion (a procedure that calls itself). But this is very non-standard.)
• (We can speculate where the rule comes from: it allows theimplementer to do the returns by patching the code at run-time.)
11 March 2003
IT52/IS22 COBOL 32
11 March 2003 IT52/IS22 COBOL 63
Out-of-line PERFORM : loops
• There are three other optional additions: these give us varioustypes of loop
[num TIMES]
[UNTIL condition]
[VARYING ident FROM num BY num UNTIL condition]
– num is an integer variable or constant– we shall look at conditions in detail later– “until” here describes a test that (by default) is done at the
top of the loop (a “leading” test)PERFORM Read-Line 2 TIMES
PERFORM Read-Line UNTIL End-File = "Y"
PERFORM Add-up VARYING i FROM 1 BY 1 UNTIL i > 10
11 March 2003 IT52/IS22 COBOL 64
Types of loop
• The use of these is obvious:• If you don’t need a loop variable inside the loop
– For a condition-controlled loop, equivalent to while, useplain UNTIL condition
– For a count-controlled loop, use plain num TIMES• But if you do need a loop variable inside the loop, use VARYING• As an example, let’s compute factorials:
1! is 12! is 2*1 = 23! is 3*2*1 = 6
– factorials are used in all sorts of ways (for example, incomputing probabilities)
– they get very big!
11 March 2003
IT52/IS22 COBOL 33
11 March 2003 IT52/IS22 COBOL 65
PERFORM-VARYING* Form factorial n DATA DIVISION. WORKING-STORAGE SECTION. 77 i PIC 99. 77 n PIC 99. 77 fact PIC 99999. PROCEDURE DIVISION. DISPLAY "Enter n: " WITH NO ADVANCING ACCEPT n MOVE 1 TO fact PERFORM Mult-para VARYING i FROM 1 BY 1 UNTIL i > n DISPLAY n, "! is ", fact STOP RUN. Mult-para. MULTIPLY i BY fact ON SIZE ERROR DISPLAY "Overflow” STOP RUN END-MULTIPLY.
11 March 2003 IT52/IS22 COBOL 66
Loops (continued) : In-line PERFORM
• In the 74 Standard, repeatedly performing a paragraph was theonly form of loop
• But the 85 Standard introduced in-line loops. Here the code-sequence follows the verb.
PERFORM UNTIL No-more = "Y" ... END-PERFORM
PERFORM VARYING i FROM 1 BY 1 UNTIL i > 10 ... END-PERFORM
• If the body of the loop is fairly small, then use in-line code
11 March 2003
IT52/IS22 COBOL 34
11 March 2003 IT52/IS22 COBOL 67
Sample program: count-controlled out-of-line loop* Average of five numbers read from keyboard DATA DIVISION. WORKING-STORAGE SECTION. 77 x PIC 999. 77 average PIC 999. 77 total PIC 9999. 77 i PIC 9.* PROCEDURE DIVISION. Main-para. MOVE ZERO TO total PERFORM Read-para 5 TIMES DIVIDE 5 INTO total GIVING average ROUNDED DISPLAY "Average is " average STOP RUN. Read-para.* Read a number from a line and add to "total" DISPLAY "Please enter a number: " WITH NO ADVANCING ACCEPT x ADD x TO total.
11 March 2003 IT52/IS22 COBOL 68
Sample program re-written with in-line loop
• We can re-write this to use in-line code
PROCEDURE DIVISION. Main-para. MOVE ZERO TO total PERFORM 5 TIMES DISPLAY "Please enter a number: " WITH NO ADVANCING ACCEPT x ADD x TO total END-PERFORM DIVIDE 5 INTO total GIVING average ROUNDED DISPLAY "Average is " average STOP RUN.
• In this case (because the code is short) the in-line version isprobably clearer
11 March 2003
IT52/IS22 COBOL 35
11 March 2003 IT52/IS22 COBOL 69
Loops (continued): trailing test
• Leading tests are far more common than trailing tests• We can obtain a trailing test (Pascal REPEAT-UNTIL, or C (or
Java) do-while) by inserting the optional element WITH TESTAFTER
* Perform at least once PERFORM Body-para WITH TEST AFTER UNTIL Got-one = "Y"
* Perform 0 to n times PERFORM Body-para VARYING i FROM 1 BY 1 UNTIL i > n
* Perform at least once PERFORM Body-para WITH TEST AFTER VARYING i FROM 1 BY 1 UNTIL i = n
11 March 2003 IT52/IS22 COBOL 70
Writing conditions (simplified)
• Conditions can be simple or complex.. Here are two “simple”ones:
Tax = 42
Tax NOT > 100
• Paradoxically, complex ones are easy: they are just simple onesconnected with AND OR brackets and NOT
Tax > 100 AND NOT (Age > 65)
• “Simple” ones are quite complicated to describe:– Relation– Class– Condition-name– (Sign (redundant: can use relation))– (Switch-status (specialised))
11 March 2003
IT52/IS22 COBOL 36
11 March 2003 IT52/IS22 COBOL 71
Relation conditions
• These have the form:arith-exp rel-op arith-exp
– arith-exp is “arithmetic expression”: in the simplest case,just a variable name or a constantTax42(Net + Markup) * 1.175
– a rel-op is a “relation operator”: > >= = < <= possiblypreceded by NOT (examples on previous slide)
– These can be spelled out in words if you likeAge >=21Age IS GREATER THAN OR EQUAL TO 21
– and there are multiple forms like EXCEEDS
11 March 2003 IT52/IS22 COBOL 72
The evaluation of relation conditions
• If both operands are simple numeric, ordinary rules apply• If both are non-numeric, then
– compare chars l-to-r– pad shorter with trailing spaces (unlike e.g. C)– use collating sequence implied (native) or specified inOBJECT-COMPUTER paragraph
• If mixed (!)– if the numeric is integer then it’s treated as a sequence of
characters– otherwise it is an error (but it’s not clear where this error is
detected: the MF compiler doesn’t fault it)– but these are shady dealings anyhow
11 March 2003
IT52/IS22 COBOL 37
11 March 2003 IT52/IS22 COBOL 73
Class condition
• The class condition has the formident IS [NOT] class-name
• the predefined class-names are NUMERIC, ALPHABETIC,ALPHABETIC-LOWER and ALPHABETIC-UPPER
WORKING-STORAGE SECTION.77 Month PIC AAA.PROCEDURE DIVISION. DISPLAY "Please enter a month, JAN to DEC” ACCEPT Month IF Month NOT ALPHABETIC-UPPER DISPLAY "Wrong Format" ; STOP RUN END-IF
• This is useful, but the example is rather crude in its approach.We can do better using condition-names
11 March 2003 IT52/IS22 COBOL 74
Condition-names
• An (elementary) variable can have an associated variable calleda condition-name. We regard the condition-name as being trueor false: that is, the name itself is (all of) a simple condition
IF valid-data THEN ...
• The mechanism is best explained through an example:WORKING-STORAGE SECTION.77 Month PIC AAA. 88 Valid-Month VALUE "JAN" "FEB" "MAR" "APR" "MAY" "JUN" "JUL" "AUG" "SEP" "OCT" "NOV" "DEC".PROCEDURE DIVISION. DISPLAY "Please enter a month, JAN to DEC" ACCEPT Month IF NOT Valid-Month DISPLAY "Wrong Format" ; STOP RUN
11 March 2003
IT52/IS22 COBOL 38
11 March 2003 IT52/IS22 COBOL 75
Condition-names (continued)
• We can associate several condition-names with a variable77 Lottery-number PIC 99. 88 L-num-unlucky VALUE 13. 88 L-num-date VALUE 1 THRU 31. 88 L-num-invalid VALUE 0, 51 THRU 99.PROCEDURE DIVISION. DISPLAY "Please enter a lottery number, 1-50" ACCEPT Lottery-number IF L-num-invalid DISPLAY "That's not a valid number" ELSE DISPLAY "That's a valid number" IF L-num-date DISPLAY "Everyone chooses birthdays" END-IF IF L-num-unlucky DISPLAY "Lucky for some!" END-IF END-IF
11 March 2003 IT52/IS22 COBOL 76
Loop and condition-name
• We can put together several pieces of the preceding material: 77 Lottery-number PIC 99. 88 L-num-valid VALUE 1 THRU 50. PROCEDURE DIVISION. Main-para. PERFORM Get-num DISPLAY "That was ", Lottery-number STOP RUN.** Return valid Lottery-number, obtained from* the keyboard Get-num. PERFORM WITH TEST AFTER UNTIL L-num-valid DISPLAY "Enter a lottery number, 1-50" ACCEPT Lottery-number IF NOT L-num-valid DISPLAY "Wrong format" END-PERFORM.
11 March 2003
IT52/IS22 COBOL 39
11 March 2003 IT52/IS22 COBOL 77
Group and elementary
• So far, we have seen only two level-numbers, 77 and 88. 77 wasused for unstructured working-storage, 88 for condition-names
• Data in a COBOL program are more usually arranged in ahierarchy:
Student-record
Student-number Student-name Degree-scheme
Year Seq InitialsSurname Title
11 March 2003 IT52/IS22 COBOL 78
Hierarchical data
• The terminal nodes of the tree are elementary items: singlevariables each with a PIC (and hence a type defined by that PIC)
• The interior nodes of the tree are group items. They do not havePICs and are all of type “alphanumeric” (even though they maybe entirely composed of numeric items)
• The length of an elementary item can be deduced from its PIC• The length of a group item is the sum of the lengths of its
components
11 March 2003
IT52/IS22 COBOL 40
11 March 2003 IT52/IS22 COBOL 79
Level-numbers
• We declare these structures using level-numbers 01 to 49– reserving 01 for complete records (the top level)– leaving gaps (01, 05, 10, etc) to allow for possible definition
of intermediate layers later– 01 in Area A, others in Area B
• All items immediately subordinate to a given item should bedeclared with the same level number
11 March 2003 IT52/IS22 COBOL 80
Declaration of hierarchical data in records
DATA DIVISION.WORKING-STORAGE SECTION.01 Student-record. 05 Stu-num. 10 Stu-num-year PIC 99. 10 Stu-num-seq PIC 9(5). 05 Stu-name. 10 Stu-name-surname PIC X(20). 10 Stu-name-inits PIC X(3). 10 Stu-name-title PIC A(4). 05 Stu-degree PIC X(6).
• How long is the whole record?• It makes no sense to say ADD 1 TO Stu-num (and the compiler
should say so)• It makes complete sense to say DISPLAY Student-record
11 March 2003
IT52/IS22 COBOL 41
11 March 2003 IT52/IS22 COBOL 81
Declaration of records (continued)
• We can declare constant parts of records (in working-storage)01 Student-record-out. 05 Stu-num. 10 Stu-num-year PIC 99. 10 PIC X VALUE ":" . 10 Stu-num-seq PIC 9(5).
• In pre-85 programs, these anonymous elementary items were allgiven the name FILLER
10 FILLER PIC X VALUE ":" .
• In fact, we can have a record that is all fillers
11 March 2003 IT52/IS22 COBOL 82
Declaration of records (continued)
01 Column-headings. 05 PIC A(7) VALUE "NUMBER". 05 PIC A(8) VALUE SPACES. 05 PIC A(4) VALUE "NAME". 05 PIC A(8) VALUE SPACES. 05 PIC A(7) VALUE SPACES. 05 PIC A(6) VALUE "DEGREE".
• Then DISPLAY Column-headings will output headings in theright places for (the first version of) the student record
11 March 2003
IT52/IS22 COBOL 42
11 March 2003 IT52/IS22 COBOL 83
MOVE (first look)
• Coming from an Algol-family background we tend to think ofMOVE as being just assignment: but there is more to it than that.
MOVE {ident | literal} TO ident ...
• We speak of the source and receiving items. What happens inthe move is determined by their types. (Remember that a groupitem is alphanumeric)
• If source and receiving items are both alphabetic oralphanumeric, then the item is left-justified in the receiver andspace-filled or truncated as necessary
• Note the figurative constant ALL literalMOVE ALL "*~" TO Out-line
11 March 2003 IT52/IS22 COBOL 84
MOVE (continued)
• If source and receiving items are both numeric,– align the decimal point– truncate/zero-fill at each end– if receiver is unsigned, it gets absolute value
• It is possible to have moves between numeric and alphanumeric- the transmitted item must be an integer
• Examples of movesN-var PIC 999V99 .A-var PIC X(6) .
MOVE 12 TO N-var 01200MOVE "Ed" TO A-var Ed____MOVE 1234.567 TO N-Var 23456MOVE "Edinburgh" TO A-Var Edinbu
11 March 2003
IT52/IS22 COBOL 43
11 March 2003 IT52/IS22 COBOL 85
Corresponding
• There is a wonderful extension of MOVE. First we have to re-visit our data declarations
• The names of data-items need not be unique: they must only beunique within their wider group-item.
01 Home-address. 05 Street PIC X(20). 05 Town PIC X(20). 05 Postcode PIC X(8).01 Work-address. 05 Street PIC X(20). 05 Town PIC X(20). 05 Postcode PIC X(8).
• We make references unique by qualification by OF or INMOVE "FK9 4LA" TO Postcode OF Work-address
11 March 2003 IT52/IS22 COBOL 86
Corresponding (continued)
• The amazing move:MOVE CORRESPONDING group-item1 TO group-item2
• The move is between all pairs of elementary items within thetwo groups that match in name (and are 01-49 and not FILLER)
01 Student-record. 05 Stu-name. 10 Stu-name-surname PIC X(20). 10 Stu-name-inits PIC X(3). 10 Stu-name-title PIC A(4).* etc01 Student-out. 05 Stu-name. 10 Stu-name-title PIC A(4). 10 PIC X VALUE SPACE. 10 Stu-name-inits PIC X(3). 10 PIC X VALUE SPACE. 10 Stu-name-surname PIC X(20).
11 March 2003
IT52/IS22 COBOL 44
11 March 2003 IT52/IS22 COBOL 87
Corresponding (continued)
• Assuming we have data in Student-record (from a file,perhaps) we could say
MOVE CORRESPONDING Student-Record TO Student-outDISPLAY Student-out
• This example shows that the fields can be re-arranged in the twogroup-items
• Also, there need not be a complete correspondence: fields (oneither side) that do not match are just ignored
• This kind of MOVE is very powerful, but– you can lose track of what is copied and what is ignored– it can involve the use of lengthy identifiers (as we shall see)
11 March 2003 IT52/IS22 COBOL 88
Files: Overview
• As in most programming languages, a file will have an externalname, governed by the conventions of the host system (e.g.Transact.dat)
• But within the program it will be referred to by an internal name,governed by the conventions of the language (e.g.Transact-file)
• The two are connected at a single point in the code• In COBOL this happens in the Environment Division.• Thereafter we use the internal name
– Declaring the structure of the record(s) in the Data Division– and using the verbs OPEN, READ, WRITE and CLOSE in the
Procedure Division
11 March 2003
IT52/IS22 COBOL 45
11 March 2003 IT52/IS22 COBOL 89
Reading a (sequential) file: example plus commentary
• Starting with the Environment Division:ENVIRONMENT DIVISION.INPUT-OUTPUT SECTION.FILE-CONTROL. SELECT File-in ASSIGN TO "Input.dat" ORGANIZATION IS LINE SEQUENTIAL.
– The SELECT connects the internal name to the external– The external name here is a literal: if your OS is case-
sensitive, be very careful!– Or could be a symbolic reference (set by the OS: e.g. in an
environment variable).– Or we can have ASSIGN DYNAMIC with an alpha variable
(so we could e.g. capture the filename from the keyboard))
11 March 2003 IT52/IS22 COBOL 90
Reading a file: example plus commentary (continued)
– organiZation– Line sequential is an MF feature. It makes “... your COBOL
system ... compatible ... with the editor software in any ...system.” You must use this clause on MF for the PC. Onmost systems you can miss out the ORGANIZATION clause
• Now the Data Division:DATA DIVISION.FILE SECTION.FD File-in.01 Student-record. 05 Stu-num. Etc
• The FD prefaces the declaration of a record that will act as aninput buffer. Note the use of the internal name
11 March 2003
IT52/IS22 COBOL 46
11 March 2003 IT52/IS22 COBOL 91
Reading a file: example plus commentary (continued)
– We have (exactly) one FD for each file referenced in theEnvironment Division
– but we can have one or more descriptions at the 01 level forthat FD. We would have this if we expected records inseveral different formats. It is an implicit redefinition of theinput buffer for this file (but the lengths may vary)
• Now we have any working-storage declarations. These willinclude variables to keep track of the status of our file(s)
01 Flags. 05 File-in-eof-flag PIC A VALUE "N". 88 File-in-ended VALUE "Y".
• On to the Procedure Division. Here we shall open the file, readto the end, and close it
11 March 2003 IT52/IS22 COBOL 92
Reading a file: example plus commentary (continued)
• The syntax of OPENOPEN [INPUT internalname ...] [OUTPUT internalname ...] [EXTEND internalname ...]
OPEN INPUT File-in
• This opens the file and positions it at the start.• Now we must construct a read loop. Central fact: the only way
we can tell if we are at EOF is by trying to read: a Cobol READwill either read a record or detect EOF. We need to implementthe following algorithm:
readwhile not at EOF process record just read read
11 March 2003
IT52/IS22 COBOL 47
11 March 2003 IT52/IS22 COBOL 93
Reading a file: example plus commentary (continued)
• The syntax of READREAD internalname [INTO ident] [AT END imperative-statement] [END-READ]
– why is the INTO part optional? Because the data is alwaysread into the associated buffer (i.e. all the 01 records underthe FD): this merely gives us the option of having anothercopy somewhere else
– if the actual data read is too long, error– if it is too short, then the remainder of the buffer is (usually)
unaltered (MF line sequential will space-fill)– imperative-statement can be several statements (remember to
terminate the sequence!– If EOF but no AT END, error
11 March 2003 IT52/IS22 COBOL 94
Reading a file: example plus commentary (continued)
• We shall put our READ into its own paragraph (because it’squite a long bit of code and we need it twice)
Read-record. READ File-in AT END MOVE "Y" TO File-in-eof-flag CLOSE File-in END-READ.
• (Remember that the flag has an associated condition-name: weshall use that to control the read loop)
• Here’s the whole of the Procedure Division:
11 March 2003
IT52/IS22 COBOL 48
11 March 2003 IT52/IS22 COBOL 95
Reading a file: example plus commentary (continued)
Main-para. OPEN INPUT File-in PERFORM Read-record PERFORM UNTIL File-in-ended* Process the record (just display) DISPLAY Student-record PERFORM Read-record END-PERFORM STOP RUN.
Read-record. READ File-in AT END MOVE "Y" TO File-in-eof-flag CLOSE File-in END-READ.
11 March 2003 IT52/IS22 COBOL 96
More than one type of input record
• We saw above that there can be several 01 definitions under asingle FD
• Suppose our input data look like this:19712345Davidson21997A31311A21997A46113C19912345Wilkinson-Smyth22000S31322A22000S46122B22000S31322F
• There are two kinds of record• Header records start with ‘1’, detail records start with ‘2’
– Headers have registration-number and name– Details have semester, unit-code and grade
11 March 2003
IT52/IS22 COBOL 49
11 March 2003 IT52/IS22 COBOL 97
More than one type of input record (continued)
• We give an 01 definition for each DATA DIVISION. FILE SECTION. FD Students-file. 01 Header-rec. 05 Rec-type-H PIC X. 88 Is-header VALUE IS "1". 05 Regno PIC 9(7). 05 Student-name PIC X(30). 01 Detail-rec. 05 Rec-type PIC X. 05 Semester PIC X(5). 05 U-code PIC X(4). 05 Grade PIC XX.
• There is only one buffer area for the input record (38 bytes long)• The two 01s give different identifiers for the same area
11 March 2003 IT52/IS22 COBOL 98
More than one type of input record (continued) PROCEDURE DIVISION. OPEN INPUT Students-file PERFORM Read-S-record PERFORM UNTIL S-file-ended IF Is-header DISPLAY Regno, " ", Student-name ELSE DISPLAY " ", Semester, " ", U-code, " ", Grade END-IF PERFORM Read-S-Record END-PERFORM STOP RUN.* Read-S-Record follows ...
9712345 Davidson 1997A 3131 1A 1997A 4611 3C9912345 Wilkinson-Smyth 2000 S3132 2A 2000 S4612 2B 2000 S3132 2F
11 March 2003
IT52/IS22 COBOL 50
11 March 2003 IT52/IS22 COBOL 99
Writing a (sequential) file
• Writing a file doesn’t introduce much new material.WRITE recordname [FROM ident]
– notice the potentially confusing (but necessary) fact thatREAD references a (internal) filename but WRITE referencesa record (one of those specified under an FD). The systemwrites to the file associated with that record
– the optional FROM part gives us an implied move whichtakes place before the write. The ident must not be part ofthe file’s record-area
– the contents of the record-area are “unavailable” after thewrite
– trailing spaces are removed in Line Sequential
11 March 2003 IT52/IS22 COBOL 100
Demonstration: read, transform, write
ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT File-in ASSIGN TO "Input.dat” ORGANIZATION IS LINE SEQUENTIAL. SELECT File-out ASSIGN TO "Output.dat” ORGANIZATION IS LINE SEQUENTIAL. DATA DIVISION. FILE SECTION. FD File-in. 01 Student-record.* etc
FD File-out. 01 Student-out.* etc
11 March 2003
IT52/IS22 COBOL 51
11 March 2003 IT52/IS22 COBOL 101
Demonstration: read, transform, write (continued)
WORKING-STORAGE SECTION.01 Flags. 05 File-in-eof-flag PIC A VALUE "N". 88 File-in-ended VALUE "Y".
PROCEDURE DIVISION.Main-para. OPEN INPUT File-in OUTPUT File-out PERFORM Read-record PERFORM UNTIL File-in-ended MOVE CORRESPONDING Student-record TO Student-out WRITE Student-out PERFORM Read-record END-PERFORM CLOSE File-out STOP RUN.
* Read-record para just as before
11 March 2003 IT52/IS22 COBOL 102
Edited PICs
• We have seen how to read structured input and write structuredoutput
• So far, all our PIC clauses have been “simple”. These were allwe needed for input: but our output was very crude.
• The basic idea of “editing” : we MOVE data from a variable witha “simple” PIC to a variable with an “edited” PIC, and thiscauses formatting to take place. (Or as the target of GIVING)
• This extends the action of MOVE, adding to its power– but the basic principle remains the same: the effect of MOVE
is determined by the types of the source and receiving items– the 85 Standard introduced “de-editing” - moves from edited
items to simple items
11 March 2003
IT52/IS22 COBOL 52
11 March 2003 IT52/IS22 COBOL 103
Simple example of editing
DATA DIVISION.WORKING-STORAGE SECTION.01 Variables. 05 Simple PIC 999. 05 No-zero PIC ZZ9.PROCEDURE DIVISION. DISPLAY "Please enter a number” ACCEPT Simple MOVE Simple TO No-zero DISPLAY "Original o/p was '", Simple, "', edited format is '", No-zero, "'"
• The Z editing character gives “zero-suppression”Please enter a number4Original o/p was '004', edited format is ' 4'
11 March 2003 IT52/IS22 COBOL 104
Editing in detail: Alphanumeric edited
• Alphanumeric PICs contain Xs• Alphanumeric edited PICs contain, additionally, one or more ofB / 0 (zero). These are insertion characters that are addedduring a move.
05 Date-1 PIC XX/XXX/XXXX.05 Date-2 PIC XXBXXXBXXXX.
MOVE "25Feb1998" TO Date-1, Date-2
will give 25/Feb/1998 and 25 Feb 1998 in the targetvariables
• Notice that we can still calculate the width of a variable. Theseare 11 locations long. This is a general point: we can alwayswork out how long an item is
11 March 2003
IT52/IS22 COBOL 53
11 March 2003 IT52/IS22 COBOL 105
Editing in detail: Numeric edited
• Numeric PICs contain S 9 V• Numeric edited PICs don't (usually) contain S V , but do
contain, additionally, one or more of a range of other charactersthat control the formatting.
• Editing takes places as a result of a MOVE to a numeric-editeditem, or as the result of GIVING
• A numeric-edited data item is not numeric - the onlymeaningful things you can do with it are:
– move it to an alphanumeric– output it– you cannot do arithmetic with it
11 March 2003 IT52/IS22 COBOL 106
Numeric edited in detail
The characters in numeric edited PICs are:• , B / 0 (zero). (Simple insertion characters)
05 Num-1 PIC 9,999,999.05 Num-2 PIC 9B999B999.
MOVE 1000000 TO Num-1, Num-2
will give 1,000,000 and 1 000 000 in the target variables(more on comma later)
• the special insertion character full-stop. This replaces V andcauses an actual full-stop to appear in the result
05 DP-raw PIC 9V99 .05 DP-edited PIC 9.99 .
DIVIDE 1 BY 100 GIVING DP-raw, DP-edited
will give 001 (numeric) and 0.01 (non-numeric) in the targetvariables (more on full-stop later)
11 March 2003
IT52/IS22 COBOL 54
11 March 2003 IT52/IS22 COBOL 107
Numeric edited in detail (continued)
• £ + - DB CR as fixed insertion characters. (I am using £ toindicate currency-sign (see Slide 110).) These are fixed because
– plus or minus must be first or last in the PIC– DB or CR must be last in the PIC– £ must be first, or after plus or minus
05 Balance-out PIC £999.99BDB .
* Debit is 200 and Balance is 100SUBTRACT Debit FROM Balance GIVING Balance-out
will give £100.00 DB in the target variable• if the result is +ve then only plus is inserted: the others are
replaced by space(s).• if the result is -ve then plus is inserted as minus: the others are
inserted as themselves
11 March 2003 IT52/IS22 COBOL 108
Numeric edited in detail (continued)
• If we have repeated £ + - then these are floating insertioncharacters, “floating” because the symbol “floats” to the right, tothe first non-zero digit, with spaces coming in from the left
05 Balance-out PIC £££9.99BDB .
* Debit is 100 and Balance is 105.75SUBTRACT Debit FROM Balance GIVING Balance-out
will give __£5.75___ in the target variable (showing blanksas underscores for clarity)
if Debit is 110 and Balance is 105.75 then we get__£4.25_DB
• Z * are the zero-suppression characters. They cause leadingzeros to be replaced by space or asterisk
05 Cheque-amount PIC £**9.99 .
11 March 2003
IT52/IS22 COBOL 55
11 March 2003 IT52/IS22 COBOL 109
CURRENCY SIGN
• The compiler’s definition of the character which is the currency-symbol in PIC clauses can be set by the programmer
ENVIRONMENT DIVISION.CONFIGURATION SECTION.SPECIAL-NAMES. CURRENCY SIGN IS "£".
• You must do this before using a symbol other than thecompiler’s default (probably dollar)
• There are rules about the permissible characters– obviously, £ and $ are both allowed (can be “L” in 85)
11 March 2003 IT52/IS22 COBOL 110
More on comma
• More on comma: if floating or suppression would leave afloating or suppression character to the left of a comma, then thecomma is replaced by the floating or suppression character
05 Demo PIC Z,ZZZ,ZZ9.
If (say) 1 is moved to this, then we get ________1 and not_,___,__1
11 March 2003
IT52/IS22 COBOL 56
11 March 2003 IT52/IS22 COBOL 111
More on full-stop
• More on full-stop: full-stop terminates floating or suppression05 Demo PIC ZZZ.ZZ .
If (say) 0.01 is moved to this, then we get ___.01 and not___._1 or _____1
but if item would otherwise be all blank then that’s what weget: if zero is moved to Demo, then we get ______ and not___.__
11 March 2003 IT52/IS22 COBOL 112
Example of file input & editing
• Suppose an input file, calls.dat, contains details of individualphone calls, by extension and cost (as £ to two decimal places)
7424 000057421 027957433 00096
• We wish to print this file, formatting the cost field
ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. CURRENCY SIGN IS "£". INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT File-in ASSIGN TO "Calls.dat" ORGANIZATION IS LINE SEQUENTIAL.
11 March 2003
IT52/IS22 COBOL 57
11 March 2003 IT52/IS22 COBOL 113
Example of file input & editing (continued) DATA DIVISION. FILE SECTION. FD File-in. 01 Call-record. 05 Extension PIC 9999. 05 PIC X.* Charge in £ 05 Call-charge PIC 999V99. WORKING-STORAGE SECTION. 01 Header. 05 PIC AAAA VALUE "Extn". 05 PIC XXXX VALUE SPACES. 05 PIC AAAA VALUE "Cost". 01 Print-record. 05 Extension PIC 9999. 05 PIC X. 05 Call-charge PIC £££9.99 . 01 Flags. 05 File-in-eof-flag PIC A VALUE "N". 88 File-in-ended VALUE "Y".
11 March 2003 IT52/IS22 COBOL 114
Example of file input & editing (concluded)
PROCEDURE DIVISION. OPEN INPUT File-in PERFORM Read-record DISPLAY Header PERFORM UNTIL File-in-ended MOVE CORRESPONDING Call-record TO Print-Record DISPLAY Print-Record PERFORM Read-record END-PERFORM STOP RUN.* Read-record just as before Read-record. READ File-in AT END MOVE "Y" TO File-in-eof-flag CLOSE File-in END-READ.
11 March 2003
IT52/IS22 COBOL 58
11 March 2003 IT52/IS22 COBOL 115
Back to the Data Division - REDEFINES
• Any data item can be redefined. (This is equivalent to Pascal'svariant records or C's unions)
01 Client-record. 05 Client-name PIC X(20). 05 Client-currency PIC A(3). 05 Client-balance-stg PIC **,***.** . 05 Client-balance-yen REDEFINES Client-balance-stg PIC *,***,*** .
• This redefines the same area and so must be the same lengthPROCEDURE DIVISION. MOVE "Smith" TO Client-name MOVE "GBP" TO Client-currency MOVE 27.23 TO Client-balance-stg DISPLAY Client-Record
11 March 2003 IT52/IS22 COBOL 116
REDEFINES (continued)
This gives the outputSmith GBP****27.23
• However, if we use the other identifier: MOVE "Kawasaki" TO Client-name MOVE "JYE" TO Client-currency* 183 Yen to the £, and 27.23 * 183 = 4983 MOVE 4983 TO Client-balance-yen DISPLAY Client-Record
Then we obtainKawasaki JYE****4,983
• Formal syntax islevel new-id REDEFINES old-id [pic-clause]
11 March 2003
IT52/IS22 COBOL 59
11 March 2003 IT52/IS22 COBOL 117
REDEFINES (continued)
• Some rules:– level numbers must be the same and with no lower number
intervening:05 this04 is05 wrong REDEFINES this
– if in FILE SECTION, not 01 (same effect achieved with othermeans, as we have seen)
– either/both item(s) can be elementary (as in the currencyexample) or group05 Weight-metric PIC 9V999.05 Weight-imperial REDEFINES Weight-metric. 10 Weight-lbs PIC 99. 10 Weight-oz PIC 99.
11 March 2003 IT52/IS22 COBOL 118
REDEFINES (continued)
– same original item can be redefined more than once05 This PIC 99. 05 That REDEFINES This PIC AA. 05 Other REDEFINES This PIC XX.
– cannot redefine the redefinitions05 This PIC 99. 05 That REDEFINES This PIC AA. 05 Wrong REDEFINES That PIC XX.
– redefinitions cannot have VALUE (why?)
11 March 2003
IT52/IS22 COBOL 60
11 March 2003 IT52/IS22 COBOL 119
Using REDEFINES with condition-name
• A neat technique for inspecting several variables (e.g. errorflags) is to redefine them against a condition-name:
01 Status-area. 03 Check-flags. 05 Check-fuel PIC A VALUE "N". 05 Check-icing PIC A VALUE "N". 05 Check-runway PIC A VALUE "N". 03 All-flags REDEFINES Check-flags PIC AAA. 88 All-OK VALUE "YYY".
• Now we can replaceIF Check-fuel = "Y" AND Check-icing = "Y" AND Check-runway = "Y" THEN
– byIF All-OK THEN
11 March 2003 IT52/IS22 COBOL 120
Still in the Data Division: OCCURS
• COBOL has a simple but powerful way of declaring arrays:these are “tables”.
05 Monthly-takings OCCURS 12 TIMES PIC 999v99.
• The number-of-times must be a constant, of course (why?)• This gives us a simple array of values. Subscripts start at 1.
Subscripting is easy (but round brackets)* January’s total is in GrossMOVE Gross TO Monthly-takings(1)
• The permissible subscript forms are:integer-constant
integer-variable
integer-variable { + | - } integer constant
11 March 2003
IT52/IS22 COBOL 61
11 March 2003 IT52/IS22 COBOL 121
Simple one-dimensional table: example
* ENVIRONMENT DIVISION sets up £ as currency DATA DIVISION. WORKING-STORAGE SECTION. 01 Sales . 05 Month-takings PIC 999 OCCURS 12 TIMES. 77 Loop-var PIC 99. 77 Annual-total PIC 99999 VALUE ZERO . 77 Annual-total-out PIC £££££9 . PROCEDURE DIVISION. DISPLAY "Enter 12 sales figures”* Read and store, form total on the fly PERFORM VARYING Loop-var FROM 1 BY 1 UNTIL Loop-var > 12 ACCEPT Month-takings(Loop-var) ADD Month-takings(Loop-var) TO Annual-total END-PERFORM MOVE Annual-total TO Annual-total-out DISPLAY "Total is ", Annual-total-out
11 March 2003 IT52/IS22 COBOL 122
One-dimensional array of group item
• Any item (including a group item) can be declared with OCCURS 05 Airport-line OCCURS 4 TIMES. 10 Airport-code PIC A(3). 10 PIC X. 10 Airport-name PIC A(20).
• This is an array of records in Pascal, or an array of structs in C• How would we initialise this? If it was a large or volatile table,
from a file. If small or static, we could use constants andREDEFINES
11 March 2003
IT52/IS22 COBOL 62
11 March 2003 IT52/IS22 COBOL 123
Initialisation using REDEFINES
• We declare the same area twice, once with coarser structure andconstants, then again in full detail
DATA DIVISION.WORKING-STORAGE SECTION.01 Airports. 03 Airport-strings. 05 PIC A(24) VALUE "LHR*London Heathrow" . 05 PIC A(24) VALUE "LCY*London City" . 05 PIC A(24) VALUE "GLA*Glasgow" . 05 PIC A(24) VALUE "EDI*Edinburgh" . 03 Airport-table REDEFINES Airport-strings. 05 Airport-line OCCURS 4 TIMES. 10 Airport-code PIC A(3). 10 PIC X. 10 Airport-name PIC A(20).
11 March 2003 IT52/IS22 COBOL 124
A simple table look-up
• Now let us try table look-up 77 A-code PIC A(3) . 77 Loop-var PIC 99. PROCEDURE DIVISION. DISPLAY "Enter an airport code" ACCEPT A-code PERFORM VARYING Loop-var FROM 1 BY 1 UNTIL Loop-var > 4 OR A-code = Airport-code(Loop-var)* Might need CONTINUE here for loop body END-PERFORM IF Loop-var > 4 DISPLAY A-code, " not found" ELSE DISPLAY Airport-name(Loop-var) END-IF
11 March 2003
IT52/IS22 COBOL 63
11 March 2003 IT52/IS22 COBOL 125
What are we subscripting?
• Notice in the previous example that we had a subscript in anatural-seeming place, but surprising to a grammarian
Airport-name(Loop-var)
• This is surprising because Airport-name is the name of anitem that does not have OCCURS. It is shorthand for
Airport-name OF Airport-line(Loop-var)
11 March 2003 IT52/IS22 COBOL 126
Multi-dimensional tables
• We can declare multi-dimensional tables using our existingtools:
01 Sales-Table. 05 Month-takings OCCURS 12 TIMES. 10 Branch-takings PIC 999 OCCURS 5 TIMES VALUE ZERO.
• The order of the subscripts follows the order of declaration, e.g.we refer to Branch-takings(Month,Branch)
• Of course, when we loop across the table we can choose whichsubscript varies faster/fastest (next slide)
11 March 2003
IT52/IS22 COBOL 64
11 March 2003 IT52/IS22 COBOL 127
Looping across multi-dimensional tables
• This outputs month-within-branch: months as columns, branchesas rows
Show-table.* Transpose sales table to save paper:* display 5 rows each with 12 columns PERFORM VARYING Bloop FROM 1 BY 1 UNTIL Bloop > 5 PERFORM VARYING Mloop FROM 1 BY 1 UNTIL Mloop > 12 DISPLAY " ", Branch-takings(Mloop,Bloop) NO ADVANCING END-PERFORM DISPLAY " " END-PERFORM.
11 March 2003 IT52/IS22 COBOL 128
Tables: indexing versus subscripting
• Refer back to Slide 122: we can add an extra phrase: 05 Airport-line OCCURS 4 TIMES INDEXED BY Airport-idx. 10 Airport-code PIC A(3). 10 PIC X. 10 Airport-name PIC A(20).
– In that previous example, we now delete the (redundant)declaration of the variable Loop-var and replace everyreference to it by Airport-idx
• Although superficially nothing has changed– the format of indexing is just the same as subscripting (Slide
120)– we drive the index using PERFORM VARYING just as
before
11 March 2003
IT52/IS22 COBOL 65
11 March 2003 IT52/IS22 COBOL 129
Tables: indexing versus subscripting (continued)
• But we are “indexing” and not “subscripting”. Indexing is safer– the index cannot be declared too small– the index cannot be driven out of range– the compiler will not allow arithmetic to be done on the
index (indeed, how the index works is hidden: it may not bean integer starting at 1)
– we can only use PERFORM VARYING and SET to change theindex ourselvesSET index-name ... TO {index-name | ident | integer}
SET index-name ... { UP | DOWN } BY {ident | integer}
11 March 2003 IT52/IS22 COBOL 130
Searching an indexed table
• Also, there is a built-in lookup that we can use on indexed tablesDISPLAY "Enter an airport code"ACCEPT A-codeSET Airport-idx TO 1SEARCH Airport-line VARYING Airport-idx AT END DISPLAY A-code, " not found" WHEN A-code = Airport-code(Airport-idx) DISPLAY Airport-name(Airport-idx) END-SEARCH
– You must initialise the index (so you can start anywhere inthe table)
– The condition can be any conditional expression– There are two branches: each can contain several statements– At the end of each branch, control passes out of the search
(so only the first matching occurrence is found)
11 March 2003
IT52/IS22 COBOL 66
11 March 2003 IT52/IS22 COBOL 131
Searching a sorted table
• The coding above is only a little easier than hand-coding (but issafer). But a binary chop is much easier using the built-insearch. Remember binary chop?
– Order log(n) rather than Order n– so (e.g.) 10 comparisons not 500 when searching 1000
• First we must specify the column on which the table is (to be)sorted (the example in Parkin & Yorke, page 196, shows thiswrongly)
05 Airport-line OCCURS 10000 TIMES ASCENDING KEY Airport-code INDEXED BY Airport-idx.
11 March 2003 IT52/IS22 COBOL 132
Searching a sorted table (continued)
– Then we must ensure that the data actually are sorted on thekey column (e.g. by rearranging the lines of literals)
– now we can use the binary version:SEARCH ALL Airport-line AT END DISPLAY A-code, " not found" WHEN Airport-code(Airport-idx)= A-code DISPLAY Airport-name(Airport-idx) END-SEARCH
– Here we neither set nor vary the index-variable– the condition must have the form
WHEN key-col(index-var) = expression
– (or else be a condition-name, with a single value, on the key-column)
11 March 2003
IT52/IS22 COBOL 67
11 March 2003 IT52/IS22 COBOL 133
Tables that aren’t full
• So far we have assumed that the table is completely occupied byuseful data
– this may not always be the case• We may not know the exact number of entries at the time the
program is written (perhaps we are reading in the table from afile)
– but in classic COBOL we cannot acquire space dynamically• So we must take a guess at the maximum number of entries and
declare the table at that maximum size (OCCURS 10000 TIMES,say)
• As we read the table from the file, we must count the rows as thetable is loaded
11 March 2003 IT52/IS22 COBOL 134
Reading a table from a file: declarations
ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT Air-File ASSIGN TO "airtable.dat" ORGANIZATION IS LINE SEQUENTIAL. DATA DIVISION. FILE SECTION. FD Air-File. 01 File-record. 10 Code-field PIC X(4). 10 PIC X. 10 Name-field PIC X(16). WORKING-STORAGE SECTION. 01 Airports. 05 Airport-line OCCURS 10000 TIMES. 10 Airport-code PIC X(4) . 10 PIC X. 10 Airport-name PIC X(16). 05 Table-size PIC 99999.
11 March 2003
IT52/IS22 COBOL 68
11 March 2003 IT52/IS22 COBOL 135
Reading a table from a file: counting the rows as we read
PROCEDURE DIVISION.* Initialise table OPEN INPUT Air-file MOVE ZERO TO Table-size.* Now use standard read loop with read para PERFORM Read-airport PERFORM UNTIL Air-file-ended ADD 1 TO Table-size IF Table-size > 10000 DISPLAY "Too many airports in file” STOP RUN END-IF MOVE File-record TO Airport-line(Table-size) PERFORM Read-airport END-PERFORM DISPLAY "Table of ", Table-size, " lines built ..."
11 March 2003 IT52/IS22 COBOL 136
Tables that aren’t full, continued
• Now that we have built the table, we could write our own codeto search the table from 1 ... Table-size
• But how could we use the clever built-in SEARCHes?• As it stands, they would search the whole of the declared space
of the table (all 10,000 rows) and not just the useful data• The answer to this problem is DEPENDING ON• So the full declaration of the table now is
05 Airport-line OCCURS 10000 TIMES DEPENDING ON Table-size ASCENDING KEY Airport-code INDEXED BY Airport-idx. 10 Airport-code PIC X(4) . 10 PIC X. 10 Airport-name PIC X(16).
• Now the built-in searches will work correctly
11 March 2003
IT52/IS22 COBOL 69
11 March 2003 IT52/IS22 COBOL 137
Sorting
• We have already seen that COBOL has a built-in table-lookup.It also has a built-in (external) sort. This can save a hugeamount of programming: the programming of external sorts isnon-trivial (very)
• Overview of the simplest sort of sort:– we have an input file, and will generate an output file. We
declare these as before (but we need give only elementarydescriptions of the records)
– we must declare a working file, using SD (Sort-Merge filedescription). The records of this file must be declared sothat the sort field(s) can be referenced
– We don’t need any i/o statements other than the sort verbitself (or even anything else in the Procedure Division)
11 March 2003 IT52/IS22 COBOL 138
Basic sort: example
• We shall sort some live data: all 20,639 grades obtained in unitsin Autumn 2002. This file is 314 Kbytes in size
• A few records:1023197 NM77 2C1023180 NM77 2B1023176 NM77 2D1023195 NM77 1B
• The file is in no particular order. Let's sort it on registration-number within unit
11 March 2003
IT52/IS22 COBOL 70
11 March 2003 IT52/IS22 COBOL 139
Basic sort: example (continued)
• Remember, we need three files:ENVIRONMENT DIVISION.INPUT-OUTPUT SECTION.FILE-CONTROL. SELECT File-in ASSIGN TO "Regist.dat” ORGANIZATION IS LINE SEQUENTIAL. SELECT File-out ASSIGN TO "Sorted.dat” ORGANIZATION IS LINE SEQUENTIAL. SELECT Work-file ASSIGN TO "Work.tmp".
• We don’t know (or need to know) how the work file isorganised; also, in some systems the external name of the workfile may be conventional
11 March 2003 IT52/IS22 COBOL 140
Basic sort: example (continued):
DATA DIVISION.FILE SECTION.FD File-in.01 Registration-in PIC X(15).FD File-out.01 Registration-out PIC X(15).SD Work-file.01 Registration. 05 Stu-num PIC 9(7). 05 PIC A. 05 Unit-code PIC X(4). 05 PIC A. 05 Grade PIC X(2).
PROCEDURE DIVISION. SORT Work-file ASCENDING KEY Unit-code ASCENDING KEY Stu-num USING File-in GIVING File-out STOP RUN.
11 March 2003
IT52/IS22 COBOL 71
11 March 2003 IT52/IS22 COBOL 141
Basic sort: example (continued)
• Here’s (some of) the output file0020575 0192 W0011631 0192 2F...1123580 IT21 2B1018350 IT31 1B...9954199 XXP7 H
• Sorting is of crucial importance for commercial DP– classic sequential master-file/transaction-file merge (later)– rapid access to data via indexes
11 March 2003 IT52/IS22 COBOL 142
Sorting plus user programming
• So far, the COBOL sort gives us little more than we could haveobtained from the system’s built-in sort (in MS-DOS, Unix ..)
• But we can add our own programming ..• We can manipulate (even create) the records that are input to the
sort• The USING filename part of the verb is replaced by INPUT PROCEDURE IS proc1 [THRU proc2]
• The procs are the names of paragraphs (or sections) in theProcedure Division. (Sections, as in Check-input SECTION. ,are a way of giving the following paragraphs a collective name)
• This is sometimes called “own-coding” the input to the sort
11 March 2003
IT52/IS22 COBOL 72
11 March 2003 IT52/IS22 COBOL 143
Own-coding the input to a sort
• The basic idea is that our code repeatedly places values in thefields of the work-file record and “releases” each new record tobe included in the sort. The form is
SORT workfile ASCENDING KEY field INPUT PROCEDURE IS para GIVING outfile. ...
para. <loop> <form workfile record> RELEASE <workfile record> <end-loop> .
• It is as if the own-coding “writes” a sequence of records into theinput of the sort. Often it reads (another) file to get the data
11 March 2003 IT52/IS22 COBOL 144
Telephone bills
• Let us suppose that the University telephone exchange generatesa record for every outgoing call. These are of the form
– calling extension ; duration (minutes) ; cost-band of call (e.g.local, national, international) ; [timestamp, etc]7424 189 1 (189 minutes of local call(!))7448 027 3 (27 minutes of international call)7421 045 27424 026 17448 013 17421 156 27424 012 3
• We want to work out each extension’s bill (e.g. 7424 owes £2.87)• As a first step in processing, we decide to
– compute the cost of each call– sort by extension (this groups the data conveniently)
11 March 2003
IT52/IS22 COBOL 73
11 March 2003 IT52/IS22 COBOL 145
Telephone bills, continued
• Suppose the tariffs are– local calls are 1.0p per minute; national calls 2.5p;
international 6.0p• First, we want to work out the cost per call
7424 189 1 => 189 @ 1.0p => 7424 189.0p7448 027 3 => 27 @ 6.0p => 7446 162.0p7421 045 2 => 45 @ 2.5p => 7421 112.5p...
– then we want to sort the records by extension7421 112.57421 ......7424 189.07424 ......7446 162.07446 ......
11 March 2003 IT52/IS22 COBOL 146
Telephone bills: Own-coding the input
• We need three files, as beforeINPUT-OUTPUT SECTION.FILE-CONTROL. SELECT File-in ASSIGN TO "Calls.dat” ORGANIZATION IS LINE SEQUENTIAL. SELECT File-out ASSIGN TO "Sorted.dat” ORGANIZATION IS LINE SEQUENTIAL. SELECT Work-file ASSIGN TO "Work.tmp".
DATA DIVISION.FILE SECTION.FD File-in.01 Call-record. 05 Extension PIC 9999. 05 PIC X. 05 Duration PIC 999. 05 PIC X. 05 Band PIC 9.
11 March 2003
IT52/IS22 COBOL 74
11 March 2003 IT52/IS22 COBOL 147
Telephone bills: Own-coding the input (continued)
FD File-out.01 Call-out PIC X(9)
SD Work-file.01 Call-charge-record. 05 Extension PIC 9999. 05 Call-charge PIC 9999V9.
• We need a a table to give the cost for each band. In a realapplication we would read this from a file
WORKING-STORAGE SECTION.01 Tariff-bands. 05 Three-costs PIC X(12) VALUE "010*025*060*". 05 REDEFINES Three-costs. 10 OCCURS 3 TIMES. 15 Tariff PIC 99V9. 15 PIC X.
11 March 2003 IT52/IS22 COBOL 148
Telephone bills: Own-coding the input (continued)
• We need an item to keep track of the input file’s status (identicalto Slide 91)
01 Flags. 05 File-in-eof-flag PIC A VALUE "N". 88 File-in-ended VALUE "Y".
• Now we’re ready to go (cf Slide 140)PROCEDURE DIVISION.Main-para. SORT Work-file ASCENDING KEY Extension OF Call-charge-record INPUT PROCEDURE IS Compute-cost GIVING File-out STOP RUN.
11 March 2003
IT52/IS22 COBOL 75
11 March 2003 IT52/IS22 COBOL 149
Telephone bills: Own-coding the input (continued)
• Remember, the task of Compute-cost is to create records to besorted and “release” them to the sort
Compute-cost. OPEN INPUT File-in PERFORM Read-record PERFORM UNTIL File-in-ended MOVE Extension OF Call-record TO Extension OF Call-charge-record MULTIPLY Duration BY Tariff(Band) GIVING Call-charge RELEASE Call-charge-record PERFORM Read-record END-PERFORM.
• We see that the paragraph uses a conventional read-loop, just ason Slide 95 (Read-record is identical, and not shown here)
11 March 2003 IT52/IS22 COBOL 150
Telephone bills: Own-coding the input (continued)
• Comparing the input and output files, we see
• The results appear to be correct (if not very readable)• But actually they are just an intermediate stage: we now wish to
aggregate the records to work out each extension’s bill.• This involves own-coding of the output
7424 189 17448 027 37421 045 27424 026 17448 013 17421 156 27424 012 3
742101125 (45 @ 2.5)742103900742401890 (189 @ 1.0)742400260742400720744801620 (27 @ 6.0)744800130
11 March 2003
IT52/IS22 COBOL 76
11 March 2003 IT52/IS22 COBOL 151
Telephone bills: Own-coding the output
• As you might expect, there is quite a lot of symmetry with theinput side
– just as we replaced USING with INPUT PROCEDURE, wereplace GIVING with OUTPUT PROCEDURE (cf Slide 148)PROCEDURE DIVISION.Main-para. SORT Work-file ASCENDING KEY Extension OF Call-charge-record INPUT PROCEDURE IS Compute-cost OUTPUT PROCEDURE IS Sum-bill STOP RUN.
• So the paragraph Sum-bill will add-up the various calls madeby an extension
11 March 2003 IT52/IS22 COBOL 152
Telephone bills: Own-coding the output, continued
• We'll skip the details of the coding: but the main point is– Sum-bill will “read” the sort’s output as if it were a file– it has a read-loop, and detects end-of-file, in the same way– except it uses the verb RETURN instead of READ– just as input coding is like “writing into the sort”, so output
coding is like “reading from the sort”: RELEASE is likeWRITE , RETURN is like READ
742101125742103900742401890742400260742400720744801620744800130
7421 £5.03
7424 £2.87
7448 £1.75
11 March 2003
IT52/IS22 COBOL 77
11 March 2003 IT52/IS22 COBOL 153
Classic master/transaction processing
• The classic style of DP is based on batch processing. Wemaintain master files: changes to these files (transactions) areapplied in batches. A batch of transactions are placed in anupdate file
• The master is always sorted on unique key field(s)• The update file(s) are sorted into order on the same key field(s):
may have several transactions for the same master record• Then we read record-at-time, in order, keeping the files in step.
This means– small memory requirement as very few records in memory
simultaneously– efficient i/o because access to next record has low (average)
cost (probably already in memory)
11 March 2003 IT52/IS22 COBOL 154
On-line Transaction Processing
• We can contrast this with On-Line Transaction Processing(OLTP) in which each transaction is applied to master record(s)as soon as it is originated
• This means that all records in the master file(s) must beaccessible within a (very) short time: in practice we achieve thisby holding a much higher proportion of the file in memory
• Batch is computationally much cheaper (and in the early stagesof commercial DP was the only feasible approach)
• Batch is still a sound approach for applications where– continuously updated masters are not needed (cost of phone
call so far this month)– data is inherently cyclic (payroll, exam records)
11 March 2003
IT52/IS22 COBOL 78
11 March 2003 IT52/IS22 COBOL 155
Designing a batch application
• The application must be very robust: must survive all possibleabnormal data conditions and run to completion
• Must ensure that all data problems can be dealt with later– by editing transaction records and re-running– by appropriate administrative action (e.g. writing to the
customer)• An error-log should be produced: also, it is useful to place the
aberrant transaction records in suspense files• We can distinguish between errors in transaction records
– that can be detected in the absence of the master record:record has wrong structure, contains invalid codes
– that can only be detected by reference to master record(s): nosuch customer, customer exceeded credit limit
11 March 2003 IT52/IS22 COBOL 156
Designing a batch application (continued)
• The first kind can be dealt with in a first pass, using a stand-alone program, generating its own error log and suspense file(s)
• Then we execute the main pass, merging transaction and masterfiles
Old master New master
Suspense file
Log file
Suspense file
Log file
Transaction file Pass 1
Pass 2
11 March 2003
IT52/IS22 COBOL 79
11 March 2003 IT52/IS22 COBOL 157
Classic merge of transaction and master
• Remember, both the transaction and master files are sorted (bye.g. client-number)
• The transaction records will be of three types:– update (so there should be a matching master record)– insertion (there should not be a matching master record)– deletion (there should be a matching master record)
• A neat solution must deal cleanly with the ends of the files: itgreatly simplifies the algorithm if we use sentinels: dummy extrarecords with keys higher than any valid key
– so the Master, Transaction and Suspense files are allmaintained with sentinel records at the end
• It's neat if the suspense file is the error log as well– containing the dud transactions plus error messages
11 March 2003 IT52/IS22 COBOL 158
A sample problem
• Assume Departments are charged for the cost of phone calls.We have master records with four fields:
– Telephone extension– Chargeable department– “Owner” of the extension– Current balance (pence: negative if Dept owes)
7332M&O Dept Office -015387370M&O Dr R Thomas -010337421CS&M Dept Office -00503
• Three kinds of transaction records:– Deletions: 7370D (Delete extension 7370)– Insertions: 7427ICS&M Dr RG Clark +00000
(Insert extension 7427)– Updates: 7332U-00057 (Charge 7332 57 pence)
11 March 2003
IT52/IS22 COBOL 80
11 March 2003 IT52/IS22 COBOL 159
Sample run of batch update
7333U+00100 No master, or files unsorted7335D+00100 No master, or files unsorted7421ICS&M Dr Wibble +00000 Duplicate extension7999X+00100 Transact code not recognised9999
7332M&O Dept Office -015387370M&O Dr R Thomas -010337421CS&M Dept Office -005037424CS&M R Bland -002877448CS&M Dr SP Marsh -001759999
7332U-000577332U+001007333U+001007335D+001007421ICS&M Dr Wibble +000007427ICS&M Dr RG Clark +000007427U-000507448D7999X+001009999
7332M&O Dept Office -014957370M&O Dr R Thomas -010337421CS&M Dept Office -005037424CS&M R Bland -002877427CS&M Dr RG Clark -000509999
Old master
New master
Suspense file
Transaction
11 March 2003 IT52/IS22 COBOL 160
Batch update, algorithm
• The algorithm for batch update is fairly easy if we only haveupdates or deletions
read master and transaction fileswhile (m-id < sentinel or t-id < sentinel) if (m-id > transaction) write transaction to suspense read transaction else if (m-id = t-id) if (update) do update read transaction else // deletion read master read transaction else write master to new-master read masterwrite sentinels to new-master & suspense
11 March 2003
IT52/IS22 COBOL 81
11 March 2003 IT52/IS22 COBOL 161
Files and OLTP
• So far, we have looked at files that are read serially, starting atthe beginning, as if they were on reel-to-reel tape
• Such files cannot support OLTP. For that we need direct access• Of course, disc is inherently direct access: we have the h/w• So we just need language features to support it• COBOL, like e.g. C, supports access-by-position-in-file - in
COBOL’s case,– this is called RELATIVE organisation– access is by record position (1, 2, 3, ...) in the file
• If the record position is inherently meaningful (e.g. data onRoom1, Room 2 ...) then this is all we need
• But in most cases our key fields do not run 1, 2, 3, ...
11 March 2003 IT52/IS22 COBOL 162
Indexes
• The programmer must know how to map between features ofinterest in the data (key values such as student number) andposition in file. This is an index
• (Most of) the index is held in memory: (most of) the main file isnot.
001 Smith ...002 Jones ...003 Robinson ...004 Farquharson005 Wu ......
9900018 0039905924 0019907013 005...
Main fileIndex
11 March 2003
IT52/IS22 COBOL 82
11 March 2003 IT52/IS22 COBOL 163
Managing indexes
• Under such an arrangement, the programmer is responsible forbuilding and maintaining the index and for providing fast look-up (e.g. binary search)
• This is non-trivial, especially if we allow inserts and deletions• COBOL will do all this work for us. If we use INDEXED
organisation then the index becomes part of the file structure andall operations on it are handled for us.
• The facilities are very easy to use• Of course, we do not know how any particular COBOL system
implements them: but, in general, files of this kind can beunbalanced by “lumpy” inserts so that the retrieval of somerecords becomes slow
11 March 2003 IT52/IS22 COBOL 164
Loading an indexed file
• To avoid this, we load as high a proportion of records as possiblein one pass, in sorted order
• The easiest way of doing this is to adapt the basic sort of Slides139-142. Not many changes are needed.
• Suppose that we want a file with one record per student, indexedby registration number. Suppose that the (unsorted) inputrecords are up to 60 columns long, with the registration numberat the start, like this:
9755864 Ms ABCSmith ..9943814 Mr DE Jones ..9612537 MissAN Other ..
11 March 2003
IT52/IS22 COBOL 83
11 March 2003 IT52/IS22 COBOL 165
Loading an indexed file (continued)* Create an indexed file ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT File-in ASSIGN TO "idxin.dat" ORGANIZATION IS LINE SEQUENTIAL. SELECT File-out ASSIGN TO "idxout.dat" ORGANIZATION IS INDEXED ACCESS MODE IS SEQUENTIAL RECORD KEY IS Stu-num. SELECT Work-file ASSIGN TO "Work.tmp". DATA DIVISION. FILE SECTION. FD File-in. 01 Student-in PIC X(60). FD File-out. 01 Student-out. 05 Stu-num PIC 9(7). 05 Text-field PIC X(53). SD Work-file. 01 Student-work. 05 Work-num PIC 9(7). 05 Text-field PIC X(53).
11 March 2003 IT52/IS22 COBOL 166
Loading an indexed file (continued)
• Notes on the previous slide:– Obviously, the key field must occur in an FD associated with
the file (PC MF requires it to be unique).– This means that the record description of the output file has
to be expanded to show the key field.• The Procedure Division still contains only the SORT verb
PROCEDURE DIVISION. SORT Work-file ASCENDING KEY Work-num USING File-in GIVING File-out STOP RUN.
• The file thus created cannot (on most systems) be manipulatedby (e.g.) editors. But with ACCESS IS SEQUENTIAL we canread (and, say, list) it using our existing COBOL techniques
11 March 2003
IT52/IS22 COBOL 84
11 March 2003 IT52/IS22 COBOL 167
Direct access to an indexed file
• To obtain direct access, we make a number of changes to themethods we used with sequential files
– Change the SELECT to use ACCESS IS RANDOM– In the Procedure Division, change the OPEN to use OPEN I-O internal-name
• Now, to read a record from anywhere, we move the required keyvalue to the key field
MOVE 9712345 TO Stu-num
and then read. If successful, this will bring in the rest of9712345’s data into the record.READ internal-name [INVALID KEY imperative-statement] [NOT INVALID KEY imperative-statement] [END-READ]
11 March 2003 IT52/IS22 COBOL 168
Direct access to an indexed file (continued)
• As usual, these are two possible branches each of which cancontain several statements
• It would be very bad practice not to code the “invalid” branch(no-such-record)
• To write to the file: assemble data in the fields of the record andeither write (if the key value ought not to be in the file already)or rewrite (if it should be)
[RE]WRITE record-name [INVALID KEY imperative-statement] [NOT INVALID KEY imperative-statement] [END-WRITE]
• Once again it would be bad practice not to code the “invalid”branch (wrong assumption about existence of key)
11 March 2003
IT52/IS22 COBOL 85
11 March 2003 IT52/IS22 COBOL 169
Direct access to an indexed file (continued)
• We can delete: once again we move the required key-value tothe key-field before using:
DELETE internal-name [INVALID KEY imperative-statement] [NOT INVALID KEY imperative-statement] [END-DELETE]
• There are also facilities to START reading sequentially from anypoint in the file
• All of the above can save a huge amount of programming• Notice that it may be advisable to occasionally rewrite an
indexed file in one sequential pass. The new index will not haveany unbalanced parts that may have been present in the old one
11 March 2003 IT52/IS22 COBOL 170
Some useful verbs: EVALUATE
• At its simplest, EVALUATE is like the C/Java switch:DISPLAY "Please enter a character"ACCEPT cEVALUATE c WHEN "Y" DISPLAY "yes" WHEN "N" DISPLAY "no" WHEN OTHER DISPLAY "neither Y nor N" END-EVALUATE
• As usual, there can be multiple statements in each branch• But this just begins to scratch the surface of the verb• The case values can be ranges
EVALUATE age WHEN 0 THRU 16 DISPLAY "School" WHEN 17 THRU 65 DISPLAY "Work" WHEN OTHER DISPLAY "Retired" END-EVALUATE
11 March 2003
IT52/IS22 COBOL 86
11 March 2003 IT52/IS22 COBOL 171
EVALUATE (continued)
• The cases can test different conditions EVALUATE TRUE WHEN NOT (sex="F" OR sex="M") DISPLAY "Sex incorrect" WHEN sex="F" DISPLAY "Woman" WHEN age<35 DISPLAY "Young man" WHEN OTHER DISPLAY "Old man" END-EVALUATE
• In fact, EVALUATE is designed to encode Decision Tables
InputsAge Sex
Action
0-16 Any “School”17-60 Any “Work”61-65 Male “Work”
Other “Retired”
11 March 2003 IT52/IS22 COBOL 172
EVALUATE (continued)
• Here's that table in COBOL* Assume sex already checked as M or F EVALUATE age ALSO sex WHEN 0 THRU 16 ALSO ANY DISPLAY "School" WHEN 17 THRU 60 ALSO ANY DISPLAY "Work" WHEN 61 THRU 65 ALSO "M" DISPLAY "Work" WHEN OTHER DISPLAY "Retired" END-EVALUATE
• The verb tries to match each row to the column-headings: itexecutes the action of the first row that matches completely
• The decision table can have as many input columns as we like• The action part can be a sequence of statements, terminated by
the next WHEN or by END-EVALUATE
11 March 2003
IT52/IS22 COBOL 87
11 March 2003 IT52/IS22 COBOL 173
String handling
• We’ll look at four string-handling topics: Referencemodification, INSPECT, STRING and UNSTRING
• The full syntax of the verbs is too complex to be given here, solook them up if you want to see their full power
• Reference-modification: we can refer to part of a data item– we add (start:length) to the original reference
05 News PIC X(20) VALUE " Here is the news ".
DISPLAY NewsDISPLAY News(2:4)
– produces Here is the newsHere
– the start and length can be variables
11 March 2003 IT52/IS22 COBOL 174
String handling: INSPECT
• The INSPECT verb deals with characters within strings.– INSPECT ... TALLYING counts occurrences of a character
or string– INSPECT ... REPLACING changes occurrences of a
character or string to another character or string– INSPECT ... CONVERTING maps one set of characters into
another(these can be BEFORE or AFTER a specified substring)
INSPECT News TALLYING N-Chars FOR ALL SPACESMOVE ZERO TO N-CharsINSPECT News TALLYING N-Chars FOR CHARACTERS BEFORE "news"
INSPECT News REPLACING ALL SPACES BY "_"
INSPECT News CONVERTING "_eristhnw" TO "*ERISTHNW"
11 March 2003
IT52/IS22 COBOL 88
11 March 2003 IT52/IS22 COBOL 175
String handling: UNSTRING
• The UNSTRING verb splits up a long string into shorter strings01 Strings. 05 News PIC X(20) VALUE " Here is the news ". 05 W OCCURS 5 TIMES PIC X(5).
UNSTRING News DELIMITED BY ALL SPACE INTO W(1), W(2), W(3), W(4), W(5) ON OVERFLOW DISPLAY "Too many words" STOP RUN END-UNSTRING
– the delimiter can be any string– the ALL option means that consecutive delimiters count as
one delimiter– so W(1) contains spaces, W(2) contains "Here ", etc
11 March 2003 IT52/IS22 COBOL 176
String handling: STRING
• The STRING verb concatenates shorter strings into one longstring
MOVE SPACES TO News STRING W(2), W(3), W(4), W(5) DELIMITED BY SPACE INTO News ON OVERFLOW DISPLAY "Destination string too short" STOP RUN END-STRING
– this gives "Hereisthenews "• The delimiter can be any string (or SIZE)• We can have different delimiters for different strings
STRING W(2), W(3) DELIMITED BY SPACE W(4), W(5) DELIMITED BY SIZE INTO News
– this gives "Hereisthe news "