The PICTURE Clause…
You can define how many characters COBOL uses to store each piece of data. You can also specify what type of characters (alphabetic, numeric, etc) that each data field can hold, and you can set up special editing attributes for those data fields. The most commonly used PICTURE symbols are X and 9, which you will use in nearly every program you write.
COBOL assigns special meaning to characters that you use in the PICTURE clause. For example, an X character used in a PICTURE clause creates one position in the computer’s memory that can hold a single character. Need to store a longer string? Use more than one X. A pair of X characters can hold two characters, three X characters can hold (you guessed it) three characters, and so on and so on.
So, if were to create a field to hold the name of my favorite animal, which happens to be my dog, I would create a PICTURE clause like this:
01 FAVORITE-PET PICTURE IS XXX.
As you can see, I’ve created space for three characters, so DOG can be stored in this field. Now, if I wanted to create a field to store the breed of my dog, which happens to be GOLDEN RETRIEVER, I would need to create a picture clause like this:
01 FAVORITE-PET PICTURE IS XXXXXXXXXXXXXXXX.
Right away, I bet you’re seeing a disadvantage to this method. It can be pretty tedious, and prone to error, to count all those X’s. So the creators of COBOL nicely allowed us to abbreviate the same PICTURE clause like this:
01 FAVORITE-PET PIC X(16).
Well that’s much easier, right? PICTURE IS can be abbreviated to PIC, and XXXXXXXXXXXXXXXX is abbreviated as X(16). I need to create space for 16 characters in order for the field to hold GOLDEN RETRIEVER. Yes, the space between the two words takes up a character position.
An X creates a space that can hold any character, whether its alphabetic, numeric, or a special character (like a dash or exclamation point). A 9 creates a space that can hold only a numeric digit. For example, the following PICTURE clause creates a space that can hold a six-digit number:
01 SOME-NUMBER PIC 9(6).
Pretty easy, right? So I can now move 123456 to my field called SOME-NUMBER. What if I mistakenly attempt to move 1234567 to this field? What will the result be? COBOL will truncate the number, and the resulting value of the field SOME-NUMBER would be 234567. The leading 1 would be lost. This can be disastrous when you are totaling numbers, so be sure you make your numeric fields large enough.
Would you use a numeric picture clause to hold a phone number, like this?
01 PHONE-NUMBER PIC 9(10).
Well you could (providing you didn’t want to store the dashes), but I wouldn’t recommend it. I would prefer to define a phone number like this:
01 PHONE-NUMBER PIC X(10).
The reason for this? I’ve always found that a good rule of thumb is this – if you may be doing math on a field, use a numeric PICTURE clause; otherwise, use a alphanumeric PICTURE clause, even if you intend for the field to always hold numeric data like a phone number, social security number, driver’s license number, zip code, etc. You probably won’t be doing any type of math on these numbers, so I just find it easier to assign them as a PIC X type. Using a PIC X will allow the entire string to be displayed in the debugger, even if the number contains leading zeros. Defining a number as PIC 9 will cause leading zeroes to be invisible while in debug mode, which can make debugging more of a challenge. We’ll discuss more about debugging in a later post.
Here all are of the available COBOL PICTURE clause symbols in a nutshell:
|A||Creates a position for an alphabetic character. (I prefer to use X).|
|B||Creates a blank position|
|C||Provides a placeholder for scaling numbers that have their decimal points beyond either the right or left of the string of digits|
|S||Creates a position for the sign of a number|
|V||Marks the position of an implied decimal point in a numeric field, but does not take up a character position|
|X||Creates a position that can be filled by any character|
|Z||Creates a position that can be filled by any numeric digit other than leading zero|
|9||Creates a position for a numeric digit|
|0||Inserts the zero character into a string|
|/||Inserts the slash character into a string|
|,||Inserts the comma character into a string|
|.||Inserts the period character into a string|
|+||Creates a position for a required sign character|
|CR||Creates a two-character position that appears as CR on negative numbers|
|DB||Creates a two-character position that appears as DB on negative number|
|*||Inserts an asterisk in place of a leading zero in a numeric field|
|$||Creates a position to display the currency sign|
I’ll admit that I pulled this list from a COBOL textbook. I’ll also admit that in more than 30 years of COBOL programming I’ve never used some of these symbols. In fact, I’ve probably only used about half of them in all those years of coding, so take what you need, and forget the rest (I surely have).