View previous topic :: View next topic
|
Author |
Message |
rohit bansal
New User
Joined: 10 Nov 2009 Posts: 3 Location: INDIA
|
|
|
|
Hi all
I am having problem finding a way to count initial spaces in a string. I tries using following code but its highly time consuming.
01 WS-VAR PIC X(32000).
.
.
.
INSPECT WS-VAR TALLYING WS-LEFT-SPACE-INDX FOR LEADING SPACES
I also tried counting it using Perform function which is taking even longer probally because my string size is too big.
Pls suggest any way to count initial spaces in a string variable without using INSPECT OR PERFORM..so that it consumes less CPU time.
Thanks in advance
Rohit |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
Looking at individual characters is a time-consuming process. You probably will not be able to do much, if anything, to reduce the CPU consumption. |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
Quote: |
I also tried counting it using Perform function which is taking even longer probally because my string size is too big. |
what does your PERFORM statement look like?
if you are zipping thru all 32000 bytes, you need to put a delimiter on your PERFORM to stop when you encounter a non-space character.
PERFORMing with an INDEX will be faster than PERFORMing with a subscript.
INSPECT will take longer than a well coded PERFORM VARYING index-data-item.
if you would consent to describing what you have to do with the data in this
32000 byte field, we could possibly provide a better solution.
on the average, how many leading spaces are there? |
|
Back to top |
|
|
rohit bansal
New User
Joined: 10 Nov 2009 Posts: 3 Location: INDIA
|
|
|
|
Actually its that i have to find following spaces in a string and to make this question easy i asked it other way. Here is my PERFORM code
COMPUTE WS-VAR-LENGTH = LENGTH OF WS-VAR - 1
PERFORM UNTIL WS-VAR (WS-VAR-LENGTH:1) NOT = SPACE
OR WS-VAR-LENGTH < 1
SUBTRACT 1 FROM WS-VAR-LENGTH
END-PERFORM
ADD 1 TO WS-VAR-LENGTH
This way i was counting following spaces..on average these following zeroes are near 30000.
How can i improve this PERFORM?
Thanks,
Rohit |
|
Back to top |
|
|
Ronald Burr
Active User
Joined: 22 Oct 2009 Posts: 293 Location: U.S.A.
|
|
|
|
Are there any spaces imbedded IN the string BEFORE the trailing spaces? If not, then it would be faster finding the first space going forward from the start of the field rather than finding the first non-space working backwards.
If there ARE imbedded spaces in the string, what is the maximum number of spaces there can be between any two non-space characters? 2? 5? 20? If 5, for example, then it would be faster doing an
Code: |
INSPECT WS-VAR TALLYING WS-STRING-LENGTH FOR CHARACTERS BEFORE INITIAL ' ' |
where the number of spaces between apostrophes is 1 MORE than the maximum number of spaces that can occur between non-space characters in the string ( in this case, 6 ). |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
well,
as i said INDEXing is faster than subscripts, and both are much faster than reference modification.
so, redefine your 32000 byte field as a table with an occurs of 32000 of pic x(01) indexed by IDX-A (or your favorite verbiage for an index-data-item Reference Name.
then modifiy your perform to:
Code: |
PERFORM VARYING IDX-A
FROM 32000
BY -1
UNTIL PICX(01) NOT = SPACES
OR IDX-A = 1
END-PERFORM
SET WS-VAR-LENGTH TO IDX-A
|
Quote: |
on average these following zeroes are near 30000. |
are they spaces or zeros?
what is your final destination field? what is the definiton? |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
Use FUNCTION REVERSE and then look for leading spaces?
And why are you using a LENGTH function? COBOL is not like C -- a variable defined as PIC X(32000) is going to have a length of 32000, always. Variables defined with OCCURS DEPENDING ON may have a variable length but you haven't mentioned anything about ODO (yet).
Personally, I have no idea what you are trying to do at this point since we've seen you say
Quote: |
I am having problem finding a way to count initial spaces in a string. |
and
Quote: |
Actually its that i have to find following spaces in a string |
|
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hi Robert,
The seldom stated but oft repeated "I'll tell you what i think you need to know to help me" rather than simply posting the actual situation/requirement. . .
d |
|
Back to top |
|
|
Terry Heinze
JCL Moderator
Joined: 14 Jul 2008 Posts: 1249 Location: Richfield, MN, USA
|
|
|
|
Quote: |
...why are you using a LENGTH function? |
Although true, I use this technique whenever possible in case the length of WS-VAR ever changes. No need to modify the PROCEDURE DIVISION code that way. I also question the original posters task. Leading or trailing? I prefer the INSPECT method (for readability) unless there are a lot of these that need to be done. In that case you're not going to get much better performance than to use DBs code. |
|
Back to top |
|
|
rohit bansal
New User
Joined: 10 Nov 2009 Posts: 3 Location: INDIA
|
|
|
|
Hi all,
First of all i am sorry its not
Quote: |
on average these following zeroes are near 30000 |
its "spaces" only...
I did not present the whole problem because its difficult to explain..
Problem in hand is to remove the empty tags from input XML.
Here is the algo:
1)take input xml in WS-INPUT-XML PIC X(32000)
2)define an array as
01 FILLER
05 WS-PROCESS-XML OCCURS 20 TIMES.
10 FILLER PIC X(32000).
3) parse WS-INPUT-XML using XML PARSE command(event driven)
4) if XML-TEXT is not equal to space or low-values, move it to its corresponding level in WS-PROCESS-XML else parse next element( For example.
WS-INPUT-XML is
<a>
<b>
<c>ew 234</c>
<d></d>
</b>
</a>
move "ew 234" to WS-PROCESS-XML(4) thru XML PARSE events.
)
5) when tag "c" ends, if WS-PROCESS-XML(4) is not empty, STRING <c> WS-PROCESS-XML(4) </c> and clean WS-PROCESS-XML(4)
6) this way when tag "b" ends, STRING <b> WS-PROCESS-XML(3)</b>...and so on in the end we get the desired empty-tag-free XML at WS-PROCESS-XML(1)
Here the problem is in step (5) when i use STRING command. If i use DELIMITED BY SPACE, i get output as "ew". And for DELIMITED BY SIZE i need to have actual size, which is 7 in this case. How to find 7??
if i use FUNCTION REVERSE on WS-PROCESS-XML(4)...then how to proceed further?? how to get number of initial spaces? without INSPECT...
Quote: |
maximum number of spaces there can be between any two non-space characters? |
there can be any number of spaces in between "ew" and "234".
Quote: |
why are you using a LENGTH function? |
i use LENGTH function because i don't want to change my PROCEDURE DIVISION.
Quote: |
you haven't mentioned anything about ODO |
I can not use ODO within OCCURS
Rohit |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
I was talking to the programmer here who did an XML PARSE. He says it was very time consuming but handles any number of spaces automatically -- the beginning and ending tags define fields (or structures). |
|
Back to top |
|
|
Ronald Burr
Active User
Joined: 22 Oct 2009 Posts: 293 Location: U.S.A.
|
|
|
|
Well, now that you have actually explained a bit what you are doing and what problem you are encountering that you are trying to solve, the answer should be a bit easier to achieve.
According to the COBOL Language Reference:
Use the LENGTH function or the LENGTH OF special register for XML-TEXT to determine the number of bytes that XML-TEXT contains. Mind you, if the TEXT between starting and ending XML tags contains trailing spaces, then the LENGTH OF XML-TEXT will INCLUDE those trailing spaces, something that your PERFORM logic would have missed. That fact may or may not make a difference to you.
ANYWAY. . . If you set a WS item to LENGTH OF XML-TEXT, you can then use it as you wish/need.
I would suggest ( given your last example )
Code: |
01 FILLER
05 WS-PROCESS-XML OCCURS 20 TIMES INDEXED BY WS-PRINDX.
10 WS-PROCESS-LEN PIC 9(5) COMP.
10 WS-PROCESS-DATA PIC X(32000)
. . .
( in initialization routine )
SET WS-PRINDX TO 1.
PERFORM 20 TIMES
MOVE ZERO TO WS-PROCESS-LEN(WS-PRINDX)
SET WS-PRINDX UP BY 1
END-PERFORM
( in parse routine )
SET WS-PRINDX TO whatever
MOVE LENGTH OF XML-TEXT TO WS-PROCESS-LEN(WS-PRINDX)
MOVE XML-TEXT(1:WS-PROCESS-LEN)
TO WS-PROCESS-DATA(WS-PRINDX)
. . .
( in output routine )
IF WS-PROCESS-LEN = ZERO
THEN
( it's an empty tag )
ELSE
( it's not an empty tag, and you. . .)
MOVE WS-PROCESS-DATA(WS-PRINDX)
TO your output
END-IF
|
|
|
Back to top |
|
|
|