Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

unsintring in a loop? 1

Status
Not open for further replies.

miskox

Technical User
Jul 21, 2010
4
SI
Hi all,

how can I perform an UNSTRING in a loop?

For example:

I have a varible WS-MY-STRING PIC X(100) value "AB/C/D/EFGH/I"-
WS-TMP is my destination variable (PIC X(100)).

I would like to have a loop to extract a different part of the string:

1. first time I would get "AB" into a WS-TMP
2. second time in a loop would return "C" in a WS-TMP.
then: "D", "EFGH" and finally "I"

Number of delimiters ("/") varies of course, length of each part between a delimiter varies, too.

I prefer an ANSI 85 solution, I use Microsoft Cobol 5.0 (DOS version), made by MicroFocus.

Is it possible to do this with an UNSTRING command or should I use a PERFORM?

Thanks for your help.
Saso

 
What have you tried so far and where in your code are you stuck ?

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Thanks for your answer.

Well, I tried UNSTRING with a POINTER. But this does not do what I want to do.

I want to UNSTRING variable number of tokens from a string.

Code:
      $set ans85
       identification division.
       program-id.    abcd.
       working-storage section.
	01 strtmp	pic x(100).
	01 untmp	pic x(100).
	01 ws-pointer	pic 999.

       procedure division.
       p-d-z.
	move "AB/C/D/EFGH/I" to strtmp.

	move 1 to ws-pointer.
	unstring strtmp delimited by "/"
		into untmp
		with pointer ws-pointer
	end-unstring.
	display "1 " untmp.

	move 2 to ws-pointer
	unstring strtmp delimited by "/"
		into untmp
		with pointer ws-pointer
	end-unstring.
	display "2 " untmp.
	stop run.

If the code above would return "AB" and "C" then I would add a loop. But going thru the reference manual I just cannot find out if this is possible.
How can I (if possible) tell the UNSTRING statement to return 1st token, 2nd token etc. if the number of tokens is not known?

I can give you an example in an OpenVMS DCL:

Code:
$ strtmp="AB/C/D/EFGH/I"
$ cnt=0
$0:
$ untmp=f$element('cnt',"/",strtmp)
$ if untmp .eqs. "" .or. untmp .eqs. "/" then exit
$ write sys$output 'untmp'
$ cnt=cnt+1
$ goto 0

This would display

AB
C
D
EFGH
I

Hope this makes any sense.

Thanks,
Saso

P.S. Sorry for mistyped subject - tried to correct but I just can't find an EDIT button.
 
A starting point:
Code:
identification division.
program-id.    tst.
working-storage section.
   01 strtmp    pic x(100).
   01 untmp    pic x(100).
   01 ws-pointer    pic 999.
   01 I pic 99.

procedure division.
p-d-z.
   move "AB/C/D/EFGH/I" to strtmp
   move 1 to ws-pointer I
   perform until ws-pointer > 100
     unstring strtmp delimited by "/"
       into untmp
       with pointer ws-pointer
     end-unstring
     display I " " untmp
     add 1 to I
   end-perform
   stop run.

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Actually, having played with this problem before, I would just consider UNSTRINGing this in one statement into a table and then process the table afterwards. Seems to be less trouble that way.

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
Something like
assuming UNSTRING not bothered by ref mod
Code:
move "AB/C/D/EFGH/I" to strtmp.

move 1 to ws-pointer.
Perform until ws-pointer > length of strtmp
    move high-values to untmp
    unstring strtmp (ws-pointer:) delimited by "/"
        into untmp
        with pointer ws-pointer
    end-unstring
    if strtmp not = high-values
        continue
    end-if 
end-perform



- free online Compare/Diff of snippets
 
You can also move or redefines your WS-MY-STRING into an array and do a perform. example:

Working-Storage:

02 WS-MY-STRING PIC X(100) value "AB/C/D/EFGH/I"
02 MY-ARR REDEFINES WS-MY-STRING.
03 MY-ARRY OCCURS 100 TIMES.
04 MY-ARRAY PIC X(01).
02 X PIC 9(03) VALUE ZEROES.
02 Y PIC 9(03) VALUE ZEROES.
02 Z PIC 9(03) VALUE ZEROES.

Procedure division:
ADD 1 TO Z.
PERFORM VARYING X FROM 1 BY 1
UNTIL (X >= 100)
MOVE X TO Y
IF (MY-ARRAY(X) = "/")
SUBTRACT 1 FROM Y
MOVE MY-ARRAY(Z:Y) TO WS-TMP
COMPUTE Z = X + 1
END-IF
END-PERFORM.
 
More...

You may have to account what is the last character of your
WS-MY-STRING.

UNTIL (X >= 100)
or (MY-ARRAY(X) = " ").... the perform will stop when a blank is encountered.
 
First, thank you all. I will check all these possibilites tomorrow (because of a time difference). I will post my results tomorrow.

Again, thank you all.
Saso
 
Far too many years ago than I care to remember, I had a similar problem and I solved it by determining what the maximum number of elements there could possibly by in the field to be unstrung, and writing an unstring statement along the following lines:
Code:
UNSTRING WS-MY-STRING DELIMITED BY '/' INTO
WS-STRING-1 DELIMITER IN WS-DLIM-1,
WS-STRING-2 DELIMITER IN WS-DLIM-2,
WS-STRING-3 DELIMITER IN WS-DLIM-3,
ETC.
WS-STRING-1/2/3 etc. were elements in a redefined table that I could then access with a subscript.

Not sure if this helps or is as good as some of the suggestions above, but thought I'd post it as an alternative solution.

Marc
 
I checked all the versions you provided.
I will use the first solution (PHV's solution).
I see I was not far from the solution myself. Mistake I made was adding 1 to the UNSTRING POINTER. I didn't know that it gets updated automaticaly.
If I remove

Code:
move 2 to ws-pointer

from my code it works, too.

Again, thank you all.

Saso
 
I like PHV's solution. It is more flexible than UNSTRING'ing into a table since it does not require you to know in advance the maximum number tokens that can be expected.

One further suggestion: add an "OR ALL SPACES" to the DELIMITED BY clause. This will ensure that the last token (from the example in the O/P) is identified as "I" and not "I ". Not terribly important in the context of the examples given above, but generally this solution is the building block for something more complicated, and in those cases, generally knowing you have just "I" and not "I" followed by bunch of spaces can save you from having to also figure out how many spaces you have to ignore (even if it is easy to calculate).

There are some excellent past examples in this forum for dealing with the UNSTRING verb. If you click on the "Search" tab above and search for "UNSTRING" you will find them. [thread209-1520795] seems particularly relevant to the current topic.

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

Razalas
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top