×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Reading a field backwards

Reading a field backwards

Reading a field backwards

(OP)
I am working on a data conversion project and I am trying to find the zip in the field(s). It can be in adr3 or adr2 field and I have to figure out how to parse it out to a zip field. The problem is the data is not consistent. Here are some examples of what the data looks like. The input file is pic x(48) for adr1, adr2, adr3. We are moving to a file where the maximum field length is 28. If zip is not in adr3 than I need to look for it in adr2.

Suite 160 Phoenix AZ 85018
Phoenix AZ 85019
Phoenix AZ  85019
Phoenix AZ  85019-11111
Phoenix AZ  85019 11111

Any help would be appreciated!  

RE: Reading a field backwards

look into the TALLYING and WITH POINTER options of the UNSTRING verb.

http://www.csis.ul.ie/COBOL/Course/Unstring.htm

Then you will have to inspect/validate the data from there.  Hopefully the rules for a ZIP code should be obvious.

Measurement is not management.

RE: Reading a field backwards

(OP)
Thanks, for getting back to me Glenn! When I go to that page I can't see the examples. Not sure why. I will search for unstring with pointers. Thanks!

RE: Reading a field backwards

(OP)
Glenn can you post a little pseudocode or an example.  

RE: Reading a field backwards

Move your address field to a temporary of the same size.

Inspect the temporary field converting "0123456789" to ALL "*"

Inspect the temporary field tallying for characters before initial "*****"

If you don't find "*****" then zip is in the other field.  Rinse and repeat.

If you do find "*****" then the  tallying value can be used in reference modification to grab it from the address field.

Tom Morrison

RE: Reading a field backwards

(OP)
It seems I may need to unstring and then go back and inspect it. I need a good example of unstring using pointer and tallying. Since the data is never in the same format. I went to the page Glenn recommended but I cannot view the examples.

RE: Reading a field backwards

This may be oversimplified, but if the state code is surrounded by spaces ...

Unstring data-rec delimited by " AZ " or " AR " or " AL "
(etc - all state codes) into field1, field2.

Field2 should contain your zip code.

RE: Reading a field backwards

Try searching this forum for the UNSTRING verb.

Glen9999 gave a good example of the UNSTRING in the following topic thread209-1520795: Removing spaces form a Message.

Code what you mean,
and mean what you code!
But by all means post your code!

Razalas

RE: Reading a field backwards

Here's how I would do it:

1) Search backwards for the last non-blank character.

2) check the last 4 characters (not 5 per the example) for numeric.

3) if they are, check the preceding character for numeric.
   a) if the preceding character is not numeric, it is zip+4
   b) if the preceding character is numeric, it is just the zip code.

RE: Reading a field backwards

Quote:


If you don't find "*****" then zip is in the other field.  Rinse and repeat.

What if you have a 5 digit street address?  For example, this lovely home in Scottsdale, AZ?

http://www.movoto.com/az/12345-n-129th-st-scottsdale/471_4101293.htm

Quote:


I need a good example of unstring using pointer and tallying

I'm not sure using WITH POINTER would be the easiest approach with a problem like you have.  Below is a snippet out of a word counting problem we had in this forum a few years ago.  You have to initialize the variable, but what TALLYING does is tell you the actual number of fields that were used with the unstring.  Later on in the program, the table is processed with a loop using WORDS-IN-LINE as a maximum.

CODE

    04  WORDS-IN-LINE        PIC S9(5) COMP-3.

* PICK APART STRING INTO WORDS
     MOVE 0 TO WORDS-IN-LINE.
     UNSTRING KJV-DATA
       DELIMITED BY ALL SPACES
            INTO Each-Word (1)  Each-Word (2)  Each-Word (3)
                 Each-Word (4)  Each-Word (5)  Each-Word (6)
                 Each-Word (7)  Each-Word (8)  Each-Word (9)
                 Each-Word (10) Each-Word (11) Each-Word (12)
                 Each-Word (13) Each-Word (14) Each-Word (15)
                 Each-Word (16) Each-Word (17) Each-Word (18)
                 Each-Word (19) Each-Word (20)
          TALLYING WORDS-IN-LINE
      END-UNSTRING.

WITH POINTER is simply specified to keep track of a starting point.  Instead of doing it all at once, you can unstring segments within a loop until the WITH POINTER value (again numeric) hits the length of the variable you are UNSTRINGing.

Measurement is not management.

RE: Reading a field backwards

(OP)
Wow, thanks for all your great feedback. I think I might have it figured out!  

RE: Reading a field backwards

Instead of figuring out how to use for it UNSTRING you can try write your own algorithm for finding ZIP.

I don't know about ZIP-Code, but the following program works with data you posted:  

zipcode.cbl

CODE

       IDENTIFICATION DIVISION.
       PROGRAM-ID. ZIPCODE.
       AUTHOR. mikrom.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SOURCE-COMPUTER. IBM-ISERIES.
       OBJECT-COMPUTER. IBM-ISERIES.
       SPECIAL-NAMES.
           DECIMAL-POINT IS COMMA
           .

       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
       01 INPUT-ADDRESS          PIC X(40).
       01 WS-FIELDS.
          05 WS-ADDRESS          PIC X(40).
          05 WS-ADDRESS-LENGTH   PIC 9(02).
          05 WS-ZIPCODE          PIC X(12).
          05 ZIP-START           PIC 9(02).
          05 ZIP-END             PIC 9(02).
          05 ZIP-LENGTH          PIC 9(02).
          05 MINIMAL-ZIP-LENGTH  PIC 9(02).
          05 J                   PIC 9(02).
          05 WS-DATA             PIC X(80).
          05 WS-DATA-LENGTH      PIC 9(02).
          05 X                   PIC 9(02).

       PROCEDURE DIVISION.
       MAIN.
           MOVE 'Suite 160 Phoenix AZ 85018' TO INPUT-ADDRESS
           DISPLAY 'Address : ' INPUT-ADDRESS
           PERFORM PARSE-ZIPCODE
           DISPLAY 'ZIP-Code: ' WS-ZIPCODE
           MOVE 'Phoenix AZ 85019'           TO INPUT-ADDRESS
           DISPLAY 'Address : ' INPUT-ADDRESS
           PERFORM PARSE-ZIPCODE
           DISPLAY 'ZIP-Code: ' WS-ZIPCODE
           MOVE 'Phoenix AZ  85019' TO INPUT-ADDRESS
           DISPLAY 'Address : ' INPUT-ADDRESS
           PERFORM PARSE-ZIPCODE
           DISPLAY 'ZIP-Code: ' WS-ZIPCODE
           MOVE 'Phoenix AZ  85019 11111'    TO INPUT-ADDRESS
           DISPLAY 'Address : ' INPUT-ADDRESS
           PERFORM PARSE-ZIPCODE
           DISPLAY 'ZIP-Code: ' WS-ZIPCODE
           MOVE 'Phoenix AZ  85019-11111'    TO INPUT-ADDRESS
           DISPLAY 'Address : ' INPUT-ADDRESS
           PERFORM PARSE-ZIPCODE
           DISPLAY 'ZIP-Code: ' WS-ZIPCODE
      *
           GOBACK
           .

       PARSE-ZIPCODE.
           INITIALIZE WS-FIELDS
           MOVE INPUT-ADDRESS TO WS-ADDRESS
      *    Length of Address
           MOVE WS-ADDRESS TO WS-DATA
           PERFORM COMPUTE-LENGTH-OF-DATA
           MOVE WS-DATA-LENGTH TO WS-ADDRESS-LENGTH
           DISPLAY 'Length of Adddress: ' WS-ADDRESS-LENGTH
      *    Find start and end position of ZIP
           IF WS-ADDRESS(WS-ADDRESS-LENGTH:1) IS NUMERIC
      *       if possible ZIP then search for its start position
              MOVE WS-ADDRESS-LENGTH TO ZIP-END
              MOVE 5 TO MINIMAL-ZIP-LENGTH
              COMPUTE J = ZIP-END - 1
      *       parse first portion of ZIP
              PERFORM UNTIL WS-ADDRESS(J:1) IS NOT NUMERIC OR J = 0
                COMPUTE J = J - 1
              END-PERFORM
              IF (WS-ADDRESS(J:1) = '-' OR ' ') AND
                  WS-ADDRESS(J - 1:1) IS NUMERIC
      *           if second portion of zip exists then continue
                  COMPUTE J = J - 1
                  PERFORM UNTIL WS-ADDRESS(J:1) IS NOT NUMERIC OR J = 0
                    COMPUTE J = J - 1
                  END-PERFORM
              END-IF
              COMPUTE ZIP-START = J + 1
              COMPUTE ZIP-LENGTH = ZIP-END - ZIP-START + 1
              IF ZIP-START NOT = ZIP-END AND
                 ZIP-LENGTH >= MINIMAL-ZIP-LENGTH
                 MOVE WS-ADDRESS(ZIP-START:ZIP-LENGTH) TO WS-ZIPCODE
              END-IF
           ELSE
              DISPLAY 'ZIP was not found !'
           END-IF
           .

       COMPUTE-LENGTH-OF-DATA.
           COMPUTE X = 0.
           INSPECT FUNCTION REVERSE(WS-DATA)
                   TALLYING X
                   FOR LEADING SPACES.
           COMPUTE WS-DATA-LENGTH = LENGTH OF WS-DATA - X
           .
Output:

CODE

  > call zipcode                           
    Address : Suite 160 Phoenix AZ 85018   
    Length of Adddress: 26           
    ZIP-Code: 85018                  
    Address : Phoenix AZ 85019       
    Length of Adddress: 16           
    ZIP-Code: 85019                  
    Address : Phoenix AZ  85019      
    Length of Adddress: 17           
    ZIP-Code: 85019                  
    Address : Phoenix AZ  85019 11111
    Length of Adddress: 23           
    ZIP-Code: 85019 11111            
    Address : Phoenix AZ  85019-11111
    Length of Adddress: 23           
    ZIP-Code: 85019-11111            
  

RE: Reading a field backwards

If your Compiler supports the INSPECT verb and the REVERSE Intrinsic Function you can try something like this (untested):


01  L                         PIC 9(02).
01  WRK-ZIP-FLD.
     05  WRK-ZIP-1      PIC 9(05)
     05  WRK-DASH      PIC X(01)
     05  WRK-ZIP-2      PIC 9(05)  

INSPECT FUNCTION REVERSE(YOUR-ADDR-FLD) TALLYING L FOR   LEADING SPACES
COMPUTE PTR-TO-ZIP = LENGTH OF YOUR-ADDR-FLD – (L + 10)
MOVE YOUR-ADDR-FLD(PTR-TO-ZIP:11) TO WRK-ZIP-FLD
IF WRK-ZIP-1    IS NUMERIC
   AND
   WRK-SEP       = ('-' OR ' ')
   AND   
   WRK-ZIP-2    IS NUMERIC
   You have an 11 byte ZIP in WRK-ZIP-FLD
ELSE
   IF WRK-ZIP-1 IS NUMERIC
      You have a 5 byte ZIP in WRK-ZIP-FLD
   ELSE
      Try this mess again on the 2nd ADDR-FLD
   END-IF   
END-IF   
         
In English, the INSPECT stmt finds the last non-blank char in the addr field.  
The COMPUTE finds the beginning of the 5 or 11 pos ZIP.
The MOVE assumes a 5 OR 11 ZIP and puts it and prepares it for analysis.
The 1st IF looks for an 11 ZIP, the 2nd for a 5; if neither do it again in ADDR-3.


PS - I thought it was ZIP+4, but I went w/5 JIC.  

Regards, Jack.

"A problem well stated is a problem half solved" -- Charles F. Kettering
 

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close