Stripping and sorting
01 IN-BUFF PIC X(40) VALUE SPACES. DISPLAY 'Enter a string: ' NO ADVANCING. ACCEPT IN-BUFF FREE. INSPECT IN-BUFF CONVERTING ' ' TO ''. DISPLAY IN-BUFF. STOP RUN.
If you try to compile this, however, you get the message below from the compiler.
/COBOLIIX(ALL),,$NULL PAGE 0001 HP32233A.02.03  Copyright Hewlett-Packard CO. 1989 LINE SEQ COL ERROR SEV TEXT 00030 002600 53 104 Q NULL LITERAL NOT ALLOWED; REPLACED BY SPACE. 0 ERROR(s), 1 QUESTIONABLE, 0 WARNING(s) DATA AREA IS %000237 WORDS. CPU TIME = 0:00:00. WALL TIME = 0:00:00. END OF COMPILE
Now this seemed like a fairly logical syntax since most editors will let you do something like that. The COBOL compiler doesnt like it when you try to replace values of different lengths with the INSPECT statement. So what is the answer here?
01 IN-BUFF PIC X(40) VALUE SPACES. DISPLAY 'Enter a string: ' NO ADVANCING. ACCEPT IN-BUFF FREE. * * The next statement will remove all spaces from the string INSPECT IN-BUFF CONVERTING ' ' TO LOW-VALUES. DISPLAY 'No spaces ' IN-BUFF. DISPLAY 'Enter a string: ' NO ADVANCING. ACCEPT IN-BUFF FREE. * * The next statement will strip leading spaces from the string INSPECT IN-BUFF REPLACING LEADING ' ' BY LOW-VALUES. DISPLAY 'No leading spaces ' IN-BUFF. STOP RUN.
The reserved word LOW-VALUES will put a NULL character in the area where the space was. You could also specify %0 (octal zero) and get the same affect.
In some situations you may not want to have the NULLs in your data stream, so make sure you test any results and make sure you are getting what you want
There are two other things in the above code sample that may require explanation. The first is the DISPLAY statement with the NO ADVANCING directive at the end. What this will do is leave the cursor at the end of the string that you just displayed (not do a carriage return/line feed). Whats funny is in some of other popular languages you had to explicitly tell the display string to do a carriage return, but in COBOL we had to jump through hoops to make it work. This is the equivalent of a carriage control code of %320 on a PRINT or FWRITE intrinsic.
The other verb that may require explanation is the FREE directive at the end of the ACCEPT statement. What many people would do before an ACCEPT statement is MOVE SPACES to the variable they were about to ACCEPT. If the user typed in the number of characters that was equivalent to the length of the variable you would get an automatic carriage return/line feed. The user would not be able to type any more characters than the variable allowed.
By specifying FREE on the ACCEPT verb, this causes the compiler to initialize the variable for you that you are about to ACCEPT. It has the side effect of not doing the carriage return/line feed when it is full. So you could be accepting a 10 character description field, and the user could type 50 characters, thinking the whole thing would take, but only the first 10 would end up in your program
How many times have you had to read some small data set or file that has a series of codes in it and needed to sort it? It seems like a lot of work and overhead to set up an FD and SD and write them out to a file and then sort and then read them back in. Wouldnt it be nice if you could just read them into a table and then sort the table in memory? Well you can, and here is a simple way to do it.
What we are going to do is use a small bubble sort, it only requires two counters, one save buffer and one table max variable, on top of the table data.
WORKING-STORAGE SECTION. 01 SAVE-CODE PIC X(04) VALUE SPACES. 01 S1 PIC S9(4) COMP VALUE 0. 01 S2 PIC S9(4) COMP VALUE 0. 01 TABLE-MAX PIC S9(4) COMP VALUE 0. 01 CODE-TABLE. 03 CODE-DATA PIC X(04) OCCURS 100 TIMES. PROCEDURE DIVISION. A1000-INIT. * * Do whatever steps are necessary to fill CODE-TABLE with the values * you are going to use in your program. Make sure to increment * TABLE-MAX for each entry you put in the table. * * Now we are going to perform a bubble sort of the table. * PERFORM VARYING S1 FROM 1 BY 1 UNTIL S1 = TABLE-MAX PERFORM VARYING S2 FROM S1 BY 1 UNTIL S2 > TABLE-MAX IF CODE-DATA(S2) < CODE-DATA(S1) MOVE CODE-DATA(S1) TO SAVE-CODE MOVE CODE-DATA(S2) TO CODE-DATA(S1) MOVE SAVE-CODE TO CODE-DATA(S2) END-IF END-PERFORM END-PERFORM.
As you can see,
we have taken advantage of some of the features of COBOL85 by using
the in-line PERFORM statement, and the END-IF statement. Hopefully
after 15 years, this isnt news anymore, but Im always
surprised at things that people never got around to using.
Copyright The 3000 NewsWire. All rights reserved.