| Front Page | News Headlines | Technical Headlines | Planning Features | Advanced Search |
Roc Software Sponsor Message

     

Stripping and sorting

By Shawn M. Gordon


I am going to touch on some various general tips this month. Some of this will be obvious to a lot of you, but for those of you who don’t know it, it will be a real treat. I was recently talking with a friend of mine who is also a COBOL programmer, and the subject of stripping leading spaces, or all spaces in a string came up. It turns out he had tried to do this many times over the years but never could make it work. He had been trying syntax such as:

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 [85] 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 doesn’t 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). What’s 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. Wouldn’t 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 isn’t news anymore, but I’m always surprised at things that people never got around to using.

Shawn Gordon, whose S.M. Gordon & Associates firm supplies HP 3000 utilities, has worked with 3000s since 1983.
 


Copyright The 3000 NewsWire. All rights reserved.