20. Arrays
In the previous chapter we talked about copy members for the date routine. Note that we had six different error messages depending on what was wrong with the date in question. Once we get through with the date check, assuming this is an online program, we need to check for any error and if there is one, we need the statements,
if date-switch = 1
screen(24,20) “date not numeric”
end-if
if date-switch = 2
screen(24,20) “day out of range”
end-if
if date-switch = 3
screen(24,20) “month out of range”
end-if
if date-switch = 4
screen(24,20) “zero is invalid for the year”
end-if
if date-switch = 5
screen(24,20) “invalid day for February”
end-if
if date-switch = 6
screen(24,20) “that month has only 30 days”
end-if
We should use this for every date we check and we could easily make it a procedure. What we would do is move the date to be checked to a very specific new date field and then pass this date to the procedure. Once the routine is done, we would have a value for the field
date-switch,
which would tell us if the date was valid or why it wasn’t, depending on one of the six values resulting from bad data. This checking could be put into a copy member but we have another option. We can put each message into an array, with the messages, date not numeric corresponding to 1, the message, day out of range corresponding to 2 and so forth. With this in mind we won’t need to use the above if statements since we will just reference the message corresponding to
date-switch,
which is the variable we use for determining what error has to be displayed. The fields that are necessary can be seen in these statements.
define message-array character(180) element t-element character(30)
occurs 6 times structure
field character(30) value “date not numeric”
field character(30) value “day out of range”
field character(30) value “month out of range”
field character(30) value “zero is invalid for the year”
field character(30) value “invalid day for February”
field character(30) value “that month has only 30 days”
We now can replace all our
if
statements related to these errors by the three statements
if date-switch > 0
screen(24,20) t-element(date-switch)
end-if
with
t-element(date-switch)
producing one of six message based on the variable in parentheses.
date-switch
will be between 1 and 6, inclusive, since there are only that many error possibilities. We could even add other messages to the array not related to date checking. If we did, we would have to adjust the size of the array, in this case 180. In addition, the count spelled out by the keyword
occurs
would have to be larger. Then we can add error messages as we need them with only a few modifications.
In summary, the statements,
define message-array character(180) element t-element character(30)
occurs 6 times structure
field character(30) value “date not numeric”
field character(30) value “day out of range”
field character(30) value “month out of range”
field character(30) value “zero is invalid for the year”
field character(30) value “invalid day for February”
field character(30) value “that month has only 30 days”
simply define an area of 180 characters for our array, broken down into 6 pieces or messages, each one being referred to as the variable,
t-element,
which consists of 30 characters each and we shall refer to these messages by subscripting. The new keywords are
element,
occurs
and
times.
This is how we configure the array and note that the above statement not only defines but also give our array values. The subscript turns out to be the variable
date-switch
and it must be a numeric field. In this case it is between 1 and 6 inclusive since we have only 7 possible values for this field, 0, 1, 2, 3, 4, 5 or 6 and
if date-switch > 0
screen(24,20) message-array(date-switch)
end-if
guarantees that our subscript does fall within this range of 6 positive numbers. A value of 0 indicates no error at all.
Let us return to the index keyword we used earlier. This was needed to verify that the letters in the name fell within a certain range of letters and symbols. It worked rather well but suppose it didn’t work as we described and it could only look at one character at a time to see if it was found in a different string. If the variable
alpha-string
represents the set of valid characters for first name mentioned earlier, namely the letters of the alphabet, both lower case and capital letters, as well as certain special symbols, then
index(“A”, alpha-string)
would result in the value 1 since A is certainly in the string but
index(“3”, alpha-string)
would give a value of 0 since the number 3 is not in the string. With that in mind, we could still do character validity checking using these statements:
define i-sub integer(2)
define work-array character(15) element c-element character
occurs 15 times
define process-sw integer
i-sub = 0
process-sw = 0
work-array = first-name
perform check-string until process-sw > 0
check-string: i-sub = i-sub + 1
if index(c-element(i-sub), alpha-string) = 0
process-sw = 2
end-if
if i-sub = 15 and process-sw = 0
process-sw = 1
end-if
What we are doing is going through each character of the string and verifying it against the string of acceptable characters. As soon as we find that a character is not in the string, we can stop the search since we know that the first name keyed is invalid. This is handled by the statement
if index(c-element(i-sub), alpha-string) = 0,
which will end the checking. Note that when
process-sw
is 1, the name meets the requirements but a value of 2 for the variable
process-sw
means that we have encountered a character that is not in the variable
alpha-string.
We do the checking as many as 15 times because first name can have as many as 15 characters. Note that if the name is only 6 characters, the remaining 9 will be spaces but that is a valid character so the test will be satisfied. This procedure is a bit more work that using the keyword
index
as we originally described but it will get us the result that we desire. The statement
perform check-string until process-sw > 0
keeps doing the procedure
check-string
until
process-sw
is no longer 0. This is achieved in one of two ways as we discussed previously. Note that
i-sub
starts out as 0 but will be 1 next and then could eventually be 15, but not any more than that.
Now suppose that we didn’t have the keyword
index
at all, but still needed to do character validity checking. It could be done by using the
the
perform
statement. The statements to do this are
define work-array character(15) element c-element character
occurs 15 times
define c-string character(56) element t-char character value
“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz .-’”
define i-sub integer(2)
define t-sub integer(2)
define process-sw integer
define first-name character(15)
i-sub = 0
process-sw = 0
work-array = first-name
perform check-string until process-sw > 0
check-string: i-sub = i-sub + 1
perform check-character varying t-sub from 1 by 1 until t-sub > 56
if i-sub = 15 and process-sw = 0
process-sw = 1
end-if
check-character: if c-element(i-sub) = t-char(t-sub)
t-sub = 57
else
if t-sub = 56
process-sw = 2
end-if
end-if
Before looking at the statements, consider what we have to do to validate the characters of the name. We must take one letter at a time starting with the leftmost position and check it against the string of valid symbols. That string is
c-string
and if the character is in the string, we then take the next character and proceed in a similar manner. If we find that each character is in
c-string,
the name passes the validity check. However, if we find any character that is not in
c-string,
we can stop the checking and need go no further since all other parts of the name don’t have to be verified. Once again the space is a valid character