I'm a beginner to COBOL, and i'm wondering what would happen if i did something like the following:
(I know that the below code isnt runnable cobol, its just there for example)
foo pic x(5)
accept foo
and the user types in a string that is only 3 characters long (e.g. yes) would the value of foo be just "yes"? or would it fill the all 5 characters as specified at creation (for example: "(space)(space)yes" or "yes(space)(space)", or is it something else?
Thanks!
here is my code
000100 IDENTIFICATION DIVISION.
000200 *--------------------
000300 PROGRAM-ID. ZIPCODES.
000400 *--------------------
000500 ENVIRONMENT DIVISION.
000600 *--------------------
000700 CONFIGURATION SECTION.
000800 INPUT-OUTPUT SECTION.
000900 FILE-CONTROL.
001000 SELECT PRT ASSIGN TO UT-S-PRTAREA.
001100
001200 DATA DIVISION.
001300 *-------------
001400 FILE SECTION.
001500 FD PRT
001600 RECORD CONTAINS 80 CHARACTERS
001700 DATA RECORD IS LINE-PRT.
001800 01 LINE-PRT PIC X(80).
001900
002000 WORKING-STORAGE SECTION.
002100 *-----------------------
002200 EXEC SQL INCLUDE SQLCA END-EXEC.
002300
002310 01 done.
002320 02 donevar PIC x(5) VALUE 'done '.
002400 01 ZIP-RECORD.
002500 02 ZIP PIC X(5).
002600 02 ZCITY PIC X(20).
002700 02 ZSTATE PIC X(2).
002800 02 ZLOCATION PIC X(35).
002900
003000 01 H1.
003100 02 COLUMN-1 PIC X(8) VALUE 'Zip-Code'.
003200 02 FILLER PIC X(2).
003300 02 COLUMN-2 PIC X(5) VALUE 'State'.
003400 02 FILLER PIC X(2).
003500 02 COLUMN-3 PIC X(4) VALUE 'City'.
003600 02 FILLER PIC X(16).
003700 02 COLUMN-4 PIC X(14) VALUE 'Location Text'.
003800 02 FILLER PIC X(29).
003900
004000 01 L1.
004100 02 ZIP-L1 PIC X(5).
004200 02 FILLER PIC X(5).
004300 02 STATE-L1 PIC X(2).
004400 02 FILLER PIC X(5).
004500 02 CITY-L1 PIC X(20).
004600 02 LOCTXT-L1 PIC X(35).
004700 02 FILLER PIC X(28).
004800
004900 PROCEDURE DIVISION.
005000 *------------------
005100 BEGIN.
005200 OPEN OUTPUT PRT.
005220 PERFORM ZIP-LOOKUP UNTIL ZIP = done.
005600 PROG-END.
005700 CLOSE PRT.
005800 GOBACK.
005900 *****************************************************
006000 * zip code lookup *
006100 *****************************************************
006200 ZIP-LOOKUP.
006300 DISPLAY 'enter 5 digit zip code'
006400 ACCEPT ZIP
006500 EXEC SQL
006600 SELECT * INTO :ZIP-RECORD FROM ZBANK.ZIPCODE
006700 WHERE ZIP = :ZIP
006800 END-EXEC.
006801 PERFORM PRINT-H1.
006802 PERFORM PRINT-L1.
006900 PRINT-H1.
007000 MOVE H1 TO LINE-PRT
007100 WRITE LINE-PRT.
007200 PRINT-L1.
007300 MOVE ZIP TO ZIP-L1
007400 MOVE ZSTATE TO STATE-L1
007500 MOVE ZCITY TO CITY-L1
007510 STRING ZSTATE DELIMITED BY " ",", ",
007520 ZCITY DELIMITED BY SIZE INTO LOCTXT-L1
007700 MOVE L1 TO LINE-PRT
007800 WRITE LINE-PRT.
I'm trying to write the zstate before the zcity, and having it keep asking for ZIP codes as long as the input isnt 'done'
The first 5 characters entered will be moved to FOO. If fewer than 5 characters are entered then they will be placed in the left hand positions of FOO and the remaining characters (to the right) will be filled with spaces. If the user enters more than 5 charcters then only the first 5 are moved.
So to use your example if the user typed "yes" then FOO would contain "yesbb"
Best thing to do is try it!
Edit in response to updated question... I think your problem is that the condition needed to terminate the loop is set in the beginning of the loop body and not at the end. Here are a couple of commonly used techniques to solve this problem:
Pre loop read
DISPLAY 'Enter a 5 digit zip code' ACCEPT ZIP PERFORM ZIP-LOOKUP UNTIL ZIP = done. ... ... ZIP-LOOKUP. EXEC SQL SELECT * INTO :ZIP-RECORD FROM ZBANK.ZIPCODE WHERE ZIP = :ZIP END-EXEC. PERFORM PRINT-H1. PERFORM PRINT-L1. * Now get next zip code or 'done' DISPLAY 'Enter a 5 digit zip code' ACCEPT ZIP .
Guard against setting terminating condition within the loop
PERFORM ZIP-LOOKUP UNTIL ZIP = done. ... ... ZIP-LOOKUP. DISPLAY 'Enter a 5 digit zip code' ACCEPT ZIP IF ZIP NOT = DONE EXEC SQL SELECT * INTO :ZIP-RECORD FROM ZBANK.ZIPCODE WHERE ZIP = :ZIP END-EXEC PERFORM PRINT-H1 PERFORM PRINT-L1 END-IF .
Either one of the above should solve your problem. However, I would suggest trying to update your coding style to include COBOL-85 constructs. The first example above might be coded as follows:
DISPLAY 'Enter a 5 digit zip code' ACCEPT ZIP PERFORM UNTIL ZIP = done EXEC SQL SELECT * INTO :ZIP-RECORD FROM ZBANK.ZIPCODE WHERE ZIP = :ZIP END-EXEC PERFORM PRINT-H1 PERFORM PRINT-L1 DISPLAY 'Enter a 5 digit zip code' ACCEPT ZIP END-PERFORM .
The ZIP-LOOKUP paragraph has been in-lined into the PERFORM statement. For short sections of code I find this style much more readable. Also notice single sentence paragraphs (only one period at the end of a paragraph). When COBOL-85 scope terminators are used (eg. END-xxx) the need for mulitple sentences per paragraph goes away - and in fact - they should be avoided.
Another COBOL construct that you could make use of here is the 88 LEVEL
. You could use it as follows:
01 ZIP-RECORD. 02 ZIP PIC X(5). 88 DONE VALUE 'done '. ... ...
You no longer need donevar
at all. Replace your original test:
IF ZIP = DONE
with:
IF DONE
The above will be true whenever the variable ZIP
contains the value "donebb". One advantage of
doing this (other than saving one variable declaration) is that a single 88 LEVEL
name can be assigned
several values, as in:
01 ZIP-RECORD. 02 ZIP PIC X(5). 88 DONE VALUE 'done ', 'quit ', 'stop '.
When the user enters any one of done
, quit
or stop
the 88 level name DONE
evaluates to true.
Finally, I presume this is just a skeleton of the program and that the finished version will be checking for I/O errors, bad SQL codes and do basic ZIP code validation. If not, you can expect a lot of trouble down the road.
COBOL Reference material
Unfortunately there are very few good up to date resources for learning COBOL. However, one of the books I would recommend is Advanced Cobol 3rd Edition by DeWard Brown. This book provides many examples and explanations regarding COBOL program development. It also identifies whether a construct is rarely used, obsolete or essential. This is good to know since you should be developing new code using modern COBOL programming techniques (I continue to see a lot of new COBOL developed using pre-COBOL 85 coding practice - and it is horrible).
An open source guide is the OpenCOBOL Programmers Guide. This targets OpenCOBOL but much of it is applicable to any flavour of COBOL.
Finally, there are several vendors guides and manuals, many of which are available on the internet. For example Enterprise COBOL for z/OS Language Reference and Enterprise COBOL for z/OS Programming guide are freely available. Microfocus COBOL guides are also available. Search any you will find...