View previous topic :: View next topic |
Author |
Message |
Dibakar Advanced
Joined: 02 Dec 2002 Posts: 700 Topics: 63 Location: USA
|
Posted: Wed Dec 18, 2002 7:07 am Post subject: Validate every byte in a field |
|
|
I have a varible of four bytes which will have valid data only if all the four bytes are in A-Z or 0-9. I was thinking of validating all the four bytes one by one. This requires four checks. Can anyone suggest a better check for this.
Thanks,
Dibakar |
|
Back to top |
|
|
faisal Beginner
Joined: 05 Dec 2002 Posts: 8 Topics: 1
|
Posted: Wed Dec 18, 2002 12:55 pm Post subject: |
|
|
how about: >= '0000' and <= 'ZZZZ' |
|
Back to top |
|
|
Premkumar Moderator
Joined: 28 Nov 2002 Posts: 77 Topics: 7 Location: Chennai, India
|
Posted: Thu Dec 19, 2002 12:53 am Post subject: |
|
|
Wouldn't strings like 'AA}A' and such fail ? |
|
Back to top |
|
|
Dibakar Advanced
Joined: 02 Dec 2002 Posts: 700 Topics: 63 Location: USA
|
Posted: Thu Dec 19, 2002 1:48 am Post subject: |
|
|
Faisal
In VS COBOL II it would be >= 'AAAA' nad <= '9999'.
Premkumar
You are right, it will fail for some cases like 'B B '. |
|
Back to top |
|
|
DaveyC Moderator
Joined: 02 Dec 2002 Posts: 151 Topics: 3 Location: Perth, Western Australia
|
Posted: Thu Dec 19, 2002 7:01 am Post subject: |
|
|
you could test every byte in a loop
pseudo-code...
Code: |
for i = 1 to length
if ( string[i] <= 'A' and string[i] >= 'Z' and
string[i] <= '0' and string[i] >= '9' ) then do
... got an error ...
end-if
end-for
|
You could also write a routine in assembler that uses a translate table, or write a function in your language of choice to make this kind of test generic. _________________ Dave Crayford |
|
Back to top |
|
|
Dibakar Advanced
Joined: 02 Dec 2002 Posts: 700 Topics: 63 Location: USA
|
Posted: Thu Dec 19, 2002 7:39 am Post subject: |
|
|
Sorry, I forgot to mention I was looking for an answer in COBOL, without using function.
DaveyC,
I think the correct code would be
for i = 1 to length
if ( (string[i] <= 'A' OR string[i] >= 'Z') and
(string[i] <= '0' OR string[i] >= '9')) then do
... got an error ...
end-if
end-for |
|
Back to top |
|
|
taterhead Beginner
Joined: 02 Dec 2002 Posts: 7 Topics: 0
|
Posted: Thu Dec 19, 2002 9:21 am Post subject: |
|
|
Check out CLASS in the SPECIAL-NAMES section. You can lay out explicitly what you're checking for.
Code: |
SPECIAL-NAMES.
CLASS ALPHA-NUM IS
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.
...
IF MY-VAR ALPHA-NUM
yadda yadda
|
Last edited by taterhead on Thu Dec 19, 2002 9:53 am; edited 2 times in total |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
|
Posted: Thu Dec 19, 2002 9:24 am Post subject: |
|
|
Dibakar,
Try this.
Code: |
01 WS-ALPHA PIC X(01).
88 VALID-ALPHA VALUE 'A' THRU 'Z'.
88 VALID-NUM VALUE '0' THRU '9'.
01 W-STRING PIC X(04).
01 W-SUB PIC 9(01).
PROCEDURE DIVISION.
MOVE 'AB1$' TO W-STRING
PERFORM VARYING W-SUB FROM 1 BY 1 UNTIL W-SUB > 4
MOVE W-STRING(W-SUB: 1) TO WS-ALPHA
IF VALID-ALPHA OR VALID-NUM
DISPLAY 'THE STRING IN POSTION ' W-SUB ' IS VALID'
ELSE
DISPLAY 'ERROR IN STRING AT POSITION' W-SUB
END-IF
END-PERFORM
|
Hope this helps...
cheers
kolusu |
|
Back to top |
|
|
DaveyC Moderator
Joined: 02 Dec 2002 Posts: 151 Topics: 3 Location: Perth, Western Australia
|
Posted: Thu Dec 19, 2002 9:38 am Post subject: |
|
|
Actually, what I meant was
Code: |
for i = 1 to length
if ( string[i] < 'A' and string[i] > 'Z' and
string[i] < '0' and string[i] > '9' ) then do
... got an error ...
end-if
end-for
|
which will execute quicker because it doesn't need to process sequence points...
That's a joke . Thanks for your correction. _________________ Dave Crayford |
|
Back to top |
|
|
Dibakar Advanced
Joined: 02 Dec 2002 Posts: 700 Topics: 63 Location: USA
|
Posted: Thu Dec 19, 2002 9:46 am Post subject: |
|
|
Hi Taterhead,
I only code in Procedure Division and Working Storage so I guess I won't be able to use SPECIAL-NAME. The solution was really cool. |
|
Back to top |
|
|
RonB Beginner
Joined: 02 Dec 2002 Posts: 93 Topics: 0 Location: Orlando, FL
|
Posted: Thu Dec 19, 2002 10:28 am Post subject: |
|
|
FWIW,
A ( character ) test for "<'A' or >'Z'" would not fail those characters that fall between 'I' and 'J' or between 'R' and 'S'. In other words x'CA', x'CB', x'CC', x'CD', x'CE', x'CF', x'DA', x'DB', x'DC', x'DE', and x'DF' would all PASS the test. So far, the only valid solutions I've seen are the ones using SPECIAL-NAMES, and the suggestion for using an assembler translate table to do a TRT. |
|
Back to top |
|
|
R.Nickel Beginner
Joined: 02 Dec 2002 Posts: 22 Topics: 0 Location: Sydney, Australia
|
Posted: Thu Dec 19, 2002 4:00 pm Post subject: |
|
|
Quote: | I only code in Procedure Division and Working Storage |
Why ?
Using special names is 90% more efficient than doing it yourself in a loop. _________________ Rainer |
|
Back to top |
|
|
Dibakar Advanced
Joined: 02 Dec 2002 Posts: 700 Topics: 63 Location: USA
|
Posted: Fri Dec 20, 2002 12:59 am Post subject: |
|
|
I only code some copybooks for script generated code. If I make any changes anywhere else then it will be temporary as next script generated code will replace it. |
|
Back to top |
|
|
Dibakar Advanced
Joined: 02 Dec 2002 Posts: 700 Topics: 63 Location: USA
|
Posted: Fri Dec 20, 2002 4:29 am Post subject: |
|
|
Since I am checking only four bytes and not expecting curly brackets (I am expecting ' ', ',', '.' and attribute values which are smaller than X'40') I used multiple ifs checking >='A' and <='9' to keep it simple.
'88 levele's and 'perform varying's was not making much diff to LOCs or redability.
But I will wait to see more interesting solutions, like SPECIAL-NAMES.
Thanks all,
Dibakar. |
|
Back to top |
|
|
Rajeev_jha Beginner
Joined: 20 Dec 2002 Posts: 5 Topics: 0
|
Posted: Fri Dec 20, 2002 6:13 am Post subject: |
|
|
Dibakar,
I have a module that checks for all the valid characters in the keyboard or else replaces it by spaces. This was developed as our file was transmitted from mainframe to UNIX. Any any junk character from mainframe was interpreted as newline character and the whole record got broken into two lines. so what we did was to remove all the junk characters to spaces. Hope this can be of some help. You can use this to create TAB delimited file for UNIX somewhat similar to earlier solutions
Code: |
05 WS-VALID-CHARS PIC X(01).
88 C-VALID-CHAR VALUE
X'F0' X'F1' X'F2' X'F3' X'F4' X'F5' X'F6'
X'F9' X'60' X'7E' X'79' X'5A' X'F7' X'F8'
X'7C' X'7B' X'5B' X'6C' X'50' X'5C' X'4D'
X'5D' X'6D' X'4E' X'D8' X'E6' X'C5' X'D9'
X'E3' X'E8' X'E4' X'C9' X'D6' X'D7' X'4A'
X'6A' X'E0' X'C0' X'D0' X'4F' X'C1' X'E2'
X'C6' X'C7' X'C8' X'D1' X'D2' X'D3' X'5E'
X'6B' X'7A' X'E9' X'E7' X'C3' X'E5' X'C2'
X'D5' X'D4' X'6B' X'4B' X'61' X'4C' X'6E'
X'6F' X'98' X'A6' X'85' X'99' X'A3' X'A8'
X'A4' X'89' X'96' X'97' X'81' X'A2' X'84'
X'86' X'87' X'88' X'91' X'92' X'93' X'A9'
X'A7' X'83' X'A5' X'82' X'95' X'94' X'C4'
X'40' X'7F' X'7D'.
01 LS-PARM-IN.
05 LS-PARM-DESC-IN PIC X(1500).
05 LS-PARM-DESC-LENGTH PIC 9(05).
05 FILLER PIC X(25).
01 LS-PARM-OUT.
05 LS-PARM-DESC-OUT PIC X(1500).
05 FILLER PIC X(30).
PROCEDURE DIVISION USING LS-PARM-IN, LS-PARM-OUT.
MOVE LS-PARM-DESC-IN TO WS-DESC-ARRAY-REC
PERFORM VARYING WS-DESC-INDEX FROM 1 BY 1 UNTIL
WS-DESC-INDEX > LS-PARM-DESC-LENGTH
MOVE WS-DESC-IN(WS-DESC-INDEX)
TO WS-VALID-CHARS
IF C-VALID-CHAR
DISPLAY 'VALID CHARACTER'
IF WS-DESC-IN(WS-DESC-INDEX) = '"'
MOVE "'" TO WS-DESC-OUT(WS-DESC-INDEX:1)
ELSE
MOVE WS-DESC-IN(WS-DESC-INDEX)
TO WS-DESC-OUT(WS-DESC-INDEX:1)
END-IF
ELSE
DISPLAY 'INVALID CHARACTER'
MOVE SPACES TO WS-DESC-OUT(WS-DESC-INDEX:1)
DISPLAY 'INVALID CHARACTER'
MOVE SPACES TO WS-DESC-OUT(WS-DESC-INDEX:1)
END-IF
END-PERFORM
|
|
|
Back to top |
|
|
|
|