View previous topic :: View next topic
|
Author |
Message |
JOJO
New User
Joined: 06 Dec 2007 Posts: 4 Location: Jacksonville
|
|
|
|
Hi,
I am trying to parse an input file using cobol. My input file has the records I need to parse in the field IN-DBC-TEXT. Basically, I need to capture words which come after 'FROM', '.FROM' or 'JOIN'. I tried using a loop to take in the first delimited word in an array and move the rest into another field.
I think there is something wrong with moving the rest of the records to WS-DBC-REST. Could someone please help me with getting the desired output?
I-DBC-FILE has lrecl of 25296 and is a fixed block.
ExampleS of input field value in IN-DBC-TEXT:
CHANGE FROM NAME1 TO NAME2;
NAME3 JOIN NAME4 CONTROL;
CHARGE NAME5 .FROM NAME6;
And the desired output should be:
NAME1
NAME4
NAME6
Here is the main part of the code.
P200-READ-IN-FILE-RECORDS.
READ I-DBC-FILE
AT END
MOVE 'Y' TO WS-EOF
GO TO P200-EXIT.
DISPLAY IN-DBC-TBL
ADD 1 TO NUMIN.
SET INDX TO 1.
MOVE 'N' TO TBL-IND.
MOVE IN-DBC-DB TO OUT-DBC-DB
MOVE IN-DBC-TBL TO OUT-DBC-TBL
MOVE IN-DBC-TEXT TO WS-TEXT
PERFORM P250-UNSTRING THRU P250-EXIT
VARYING INDX FROM 1 BY 1
UNTIL WS-DBC-REST EQUAL TO SPACES.
P250-UNSTRING.
EVALUATE TBL-IND
WHEN 'Y'
MOVE WS-DBC-PARSE TO OUT-VW-TBL
PERFORM P350-WRITE THRU P350-WRITE-EXIT
END-EVALUATE.
UNSTRING WS-TEXT DELIMITED BY SPACE
INTO IND-WORD (INDX)
WS-DBC-REST
DISPLAY 'WS-DBC-REST ' WS-DBC-REST
MOVE WS-DBC-REST TO WS-TEXT
MOVE IND-WORD (INDX) TO WS-DBC-PARSE.
DISPLAY 'WS-DBC-PARSE' WS-DBC-PARSE
DISPLAY 'TBL-IND' TBL-IND
EVALUATE WS-DBC-PARSE
WHEN 'FROM'
WHEN '.FROM'
WHEN 'JOIN'
MOVE 'Y' TO TBL-IND
WHEN OTHER
MOVE 'N' TO TBL-IND
END-EVALUATE.
P250-EXIT.
EXIT. |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hello,
First, i believe you do not need to test ".FROM". The test for "FROM" will suffice.
You mention that the input has lrecl of 25296. Could "FROM" and/or "JOIN" exist in the record more than 1 time?
If this was my requirement, i'd probably just loop thru the input using reference modification. When i got a it, i'd unstring from that point to get the next "word". If a search word can only exist once per record, i'd only continue the loop until i found a hit. If multiples are possible, i'd continue until i was finished with the record.
I expect the code would run more efficiently if as the loop processed, the code made sure there was still more data to be parsed. |
|
Back to top |
|
|
the_gautam
Active User
Joined: 05 Jun 2005 Posts: 165 Location: Bangalore
|
|
|
|
as dick scherrer mentioned, reference modification will be a good idea in this case.
i would like to find the position of the value "FROM " in the record and then get the next characters until i find a space (i.e. the next word).
and similarly for the "JOIN " as well.
however, if the "FROM " and "JOIN " are present in the same record, then we need to do some further codings... |
|
Back to top |
|
|
JOJO
New User
Joined: 06 Dec 2007 Posts: 4 Location: Jacksonville
|
|
|
|
Thanks for your responses..
The input file used can contain more than 1 'FROM' or 'JOIN' keywords and sometimes both 'FROM' and 'JOIN'.
I would like to look into the option of using reference modification. Is there any link which has the details with examples of reference modification? I could go thru it and use it.. |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hello KP,
If you use the "SEARCH" at the top of the page, use reference modification as your keywords, and click the "Search for all terms" radio-button, you will get many "hits". Look thru them and there are several with code in the topic.
You could also look in the COBOL manual by using the "IBM Manuals" link at the top of the page. There is both a Language Reference and Programmers Guide for the most used versions of the mainframe compiler.
I'd suggest you create a small test case to become familiar with reference modification. When you have something written and have any questions, post what is not clear here and someone will be able to help. |
|
Back to top |
|
|
Mike Davisson
New User
Joined: 15 May 2008 Posts: 3 Location: New Mexico
|
|
|
|
You said...
CHANGE FROM NAME1 TO NAME2;
NAME3 JOIN NAME4 CONTROL;
CHARGE NAME5 .FROM NAME6;
And the desired output should be:
NAME1
NAME4
NAME6
I would do this:
01 THE-LENGTH PIC 9(07) VALUE len of record.
01 THE-TEXT PIC X(05) value space.
01 X PIC 9(07) VALUE ZERO.
PERFORM VARYING X FROM 1 BY 1
UNTIL X > THE-LENGTH - 6
IF WS-TEXT(X:5) = 'FROM ' OR
WS-TEXT(X:5) = 'JOIN '
MOVE WS-TEXT(X + 5:5) TO THE-TEXT
DISPLAY THE-TEXT
MOVE THE-LENGTH TO X
END-IF
END-PERFORM |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hello Mike and welcome to the forums,
I suspect the "name" after the search words will not always be the sme length.
Did you test the posted code? At a quick glance, i believe it may need a bit of work (beyond the name length). Moving THE-LENGTH back to X may not be the ticket? |
|
Back to top |
|
|
Mike Davisson
New User
Joined: 15 May 2008 Posts: 3 Location: New Mexico
|
|
|
|
dick scherrer wrote: |
Hello Mike and welcome to the forums,
I suspect the "name" after the search words will not always be the sme length.
Did you test the posted code? At a quick glance, i believe it may need a bit of work (beyond the name length). |
Okay, too bad the editor crams everything to the left margin. Let's see how this works:
Code: |
01 THE-LENGTH PIC 9(07) VALUE 25296.
01 THE-TEXT PIC X(05) VALUE SPACE.
01 X PIC 9(07) VALUE ZERO.
01 Y PIC 9(07) VALUE ZERO.
PERFORM VARYING X FROM 1 BY 1
UNTIL X > THE-LENGTH - 6
IF WS-TEXT(X:5) = 'FROM ' OR
WS-TEXT(X:5) = 'JOIN '
MOVE SPACE TO THE-TEXT
PERFORM VARYING Y FROM X + 5 BY 1
UNTIL WS-TEXT(Y:1) = SPACE OR Y > THE-LENGTH
STRING THE-TEXT DELIMITED BY ' '
WS-TEXT(Y:1) DELIMITED BY SIZE
INTO THE-TEXT
END-PERFORM
DISPLAY THE-TEXT
MOVE THE-TEXT TO wherever if you want to save it
END-IF
END-PERFORM. |
No, I haven't tested it, but I do this all the time to find various string patterns in records. Yes, with some tweaking, I believe it would work. YMMV
dick scherrer wrote: |
Moving THE-LENGTH back to X may not be the ticket? |
I'm not doing it in this version, but moving THE-LENGTH back to X is a useful way to get out of the loop when something is found. It causes X to go over the limit with the next iteration. I could have also used COMPUTE X = THE-LENGTH + 1 for the same result. I know it goes against the grain of some people's way of thinking, but I know it works --- and reliably without causing S0C4s or other abends. |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hi Mike,
Quote: |
too bad the editor crams everything to the left margin |
Please take a peek at your last post - that is done by using the "Code" tag near the top of the Rely panel. Also, next to Submit, there is a Preview function. If you click Preview, you will see your post the way it will appear to the forum, rather than the way it appears in the editor. Just make sure to Submit afterwards or your post will be gone (done that a few times ).
Quote: |
but moving THE-LENGTH back to X is a useful way to get out of the loop when something is found |
Yup, however, the requirement mentions that there may be more than one "hit" per scan.
Quote: |
The input file used can contain more than 1 'FROM' or 'JOIN' keywords and sometimes both 'FROM' and 'JOIN'. |
Quote: |
I know it goes against the grain of some people's way of thinking, but I know it works |
Very few things that will work every time (and not su** the cpu dry) go against my grain |
|
Back to top |
|
|
Mike Davisson
New User
Joined: 15 May 2008 Posts: 3 Location: New Mexico
|
|
|
|
dick scherrer wrote: |
Hi Mike,
Quote: |
too bad the editor crams everything to the left margin |
Please take a peek at your last post - that is done by using the "Code" tag near the top of the Rely panel. Also, next to Submit, there is a Preview function. If you click Preview, you will see your post the way it will appear to the forum, rather than the way it appears in the editor. Just make sure to Submit afterwards or your post will be gone (done that a few times ).
Quote: |
but moving THE-LENGTH back to X is a useful way to get out of the loop when something is found |
Yup, however, the requirement mentions that there may be more than one "hit" per scan.
Quote: |
The input file used can contain more than 1 'FROM' or 'JOIN' keywords and sometimes both 'FROM' and 'JOIN'. |
Quote: |
I know it goes against the grain of some people's way of thinking, but I know it works |
Very few things that will work every time (and not suc* the cpu dry) go against my grain |
Ohhhh! Thanks for the pointer. Yeah, I didn't use the Code tag but now I know. Thanks, again!
And, yeah, finding multiple targets in the string would require something different. How about this:
Code: |
01 THE-LENGTH PIC 9(07) VALUE 25296.
01 THE-TEXT PIC X(05) VALUE SPACE.
01 X PIC 9(07) VALUE ZERO.
01 Y PIC 9(07) VALUE ZERO.
01 THE-TABLE.
05 THE-TBL OCCURS 20 INDEXED BY TT.
10 TT-TEXT PIC X(80).
PERFORM VARYING X FROM 1 BY 1
UNTIL X > 20
MOVE SPACE TO TT-TEXT (X)
END-PERFORM.
(or INITIALIZE ......)
PERFORM VARYING X FROM 1 BY 1
UNTIL X > THE-LENGTH - 6
IF WS-TEXT(X:5) = 'FROM ' OR 'JOIN '
PERFORM VARYING Y FROM X + 5 BY 1
UNTIL WS-TEXT(Y:1) = SPACE OR Y > THE-LENGTH
END-PERFORM
IF Y > ZERO
MOVE WS-TEXT(X + 5:Y - 1) TO THE-TEXT
SET TT TO 1
SEARCH THE-TBL AT END
DISPLAY 'THE-TBL OUT OF ROOM'
WHEN TT-TEXT (TT) = SPACE
DISPLAY 'FOUND ' THE-TEXT
MOVE THE-TEXT TO TT-TEXT (TT)
END-SEARCH
END-IF
MOVE Y TO X
END-IF
END-PERFORM.
DISPLAY ' '.
DISPLAY 'FOUND THESE TARGETS:'.
PERFORM VARYING X FROM 1 BY 1
UNTIL TT-TEXT (X) = SPACE OR X > 20
DISPLAY TT-TEXT (X)
END-PERFORM. |
Dunno. Take it for what it's worth. It's what I would start with and allow testing to reveal the problems. YMMV. |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hi Mike,
Well, if JOJO is watching, i believe it is a pretty good point from which to work forward. Not to put too fine a point on it; i'd change X & Y to be comp-3.
Thanks for the effort
d |
|
Back to top |
|
|
|