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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

To find the length of a string... 1

Status
Not open for further replies.

ashykhanna

Programmer
May 27, 2002
14
IN
hello,
can anyone let me know how to find the length of a given string using cobol.
suppose,

10 ws-data pic x(64)

i move some string to this variable.i would like to find the length of the string moved to ws-data.
its very urgent.
thank you,
Ashok..
 
Hi,
Does any one know o any software/utility that will help
in tracing the exact variable that caused abend on mainframe?
Regards,
Ajit
 
hi ajit,
there is no such utility available(as far as i know).
1) but after the program abends, u can check in the spooled output and in the expanded version of the program for the DML sequence. with this u can trace the error.
2)if its a User abend, u can trace it with the corresponding error code given in the spooled output.
3) if u are pretty advanced programmer, u can even trace the error using the Offset value, generated in the spooled output.but this is the last method. its pretty difficult to do so.

bye bye,
Ashok
 
Hi Ashok

It won't be a good solution, but when i need to count how is long a string in char, i use these simple statements.

You are declaring that the field is 64 chars length, then you can apply:

WORKING-STORAGE SECTION.
01 WS-DATA PIC X(64).
01 K PIC 999.

PROCEDURE DIVISION.
LOOP.
PERFORM VARYING K FROM 64 BY -1 UNTIL WS-DATA (K:1) NOT = SPACES
CONTINUE
END-PERFORM.

Examining the K field value it would be the exact numbers of valid chars in the string.

Hope in this help

Gianni

 
Unless WS-DATA value is SPACES at which point the loop will attempt to reference WS-DATA (0:1), which is not good.

Apply FAQ faq209-1604 to this loop:
Code:
PERFORM VARYING K FROM 64 BY -1 
  UNTIL K = 0
     OR WS-DATA (K:1) NOT = SPACES
        CONTINUE
END-PERFORM.
Tom Morrison
 
This source will work, but let the computer do a lot of compares. By changing the value of K depending on boundary values of a binary search, you can reduce the processing.

I hope you know the general idea: starting with boundaries 1 and 64, you test 32. When not space, you compute (64 + 33) /2, so the next test, K will be 48. If it is space, you know that the upper boundary is at least one less and you compute (33 + 47) /2, so the next test K will be 40.

Now I like to see the best implementation of such an algorithm :)

The binary search algorithm is demonstrated on the calculator forum.

Regards,

Crox
 
Here is how I do it.

10 ws-data pic x(64).

10 just-for-chuckles pic x(64).
10 result pic 99 value zeroes.

move spaces to just-for-chuckles.
move some-string to ws-data.
unstring ws-data delimited by ' ' (two spaces)
into just-for-chuckles count in result.
** result contains string length

enjoy Bob
 
Hi

this will give sometimes problems because two spaces can be between text.

Regards,

Crox
 
Hi Crox, Dimandja, Slade and others.
I have just join this forum and yes you guys are doing a great job by providing awesome information. I have gone thru many threads and really impressed by the solution provided by you. Definitely I like to be a active part of this forum.

BTW for this thread here is a solution which is very simple and should work in any case. (comments welcome)

WORKING-STORAGE SECTION.
01 WS-DATA PIC X(30) VALUE 'ANY STRING'.
01 HOLD-DATA PIC X(60).
01 DELIM PIC X(30).
01 TEMP-DATA PIC X(30).
01 CTR PIC 9(02).

PROCEDURE DIVISION.
MAIN-PARA.
MOVE SPACES TO TEMP-DATA DELIMIT.
MOVE WS-DATA TO HOLD-DATA.
UNSTRING HOLD-DATA DELIMITED BY DELIMIT INTO
TEMP-DATA COUNT IN CTR.

DISPLAY 'TEMP-DATA' TEMP-DATA.
DISPLAY 'CTR:' CTR.

The trick is define a variable which can be used as a delimiter big enough and initialize it with spaces. The source variable should be moved to a temp-var. The length of this temp-var should be at least equal to the length of source-var + length of delimiter variable.

Thanks
Devesh
 
Let's give this one last shot. I'm making the assumption that you're counting characters until you run into all spaces. This solution doesn't matter if there any spaces imbedded in the phrase.

We'll reverse the order of the field and then count the leading spaces.

01 PHRASE PIC X(64).
01 SAVE-AREA.
03 SA-TEMP-PHRASE PIC X(64).
03 SA-SPACES PIC S9(02).
03 SA-LENGTH PIC S9(02).


MOVE FUNCTION REVERSE(PHRASE) TO SA-TEMP-PHRASE.
MOVE +0 TO SA-SPACES.
INSPECT SA-TEMP-PHRASE
TALLYING SA-SPACES FOR LEADING SPACE.
COMPUTE SA-LENGTH = LENGTH OF SA-TEMP-PHRASE
- SA-SPACES.

This works if the entire phrase is spaces - SA-SPACES = 64 so SA-LENGTH is zero. It works if the entire field is filled in - SA-SPACES = 0 so SA-LENGTH = 64. And it works for all values in between.

Lunker

 
How about something like;

05 CNTR PIC 99.
...
PROCEDURE DIVISION.
...
MOVE ZERO TO CNTR
...
INSPECT FUNCTION REVERSE (ws-data)
TALLYING CNTR
FOR LEADING SPACES

 
Heh CobolKid, Slade and ceh4702 said that almost exactly a year ago!
 
I may have missed it earlier in this thread, but in case I didn't ...

The INSPECT Function REVERSE (...) Tallying

is my favorite "self-documenting" solution. HOWEVER, depending upon the compiler, it may be one of the "poorer" performing (at run-time) solutions.

Therefore, if this is a task that you need to do in a "performance sensitive" application or within a "tight loop" in a long running application, I suggest that you check out some of the other solutions (and compare their actual run-time performance in your environment).

If on the other hand, this is a part of an application that represents a (relatively) small fraction of the run-time, then it probably doesn't matter and you (one) can take advantage of its "self-documenting" nature.
 
Hay MarcLodge
Classic textbook stuff from many years back.
I'm sure many others have posted it before.




 
Hey CobolKid,
Agree that it's textbook stuff, and I'm sure it will be posted again.

Question to the masses......What does everybody think of the INSPECT REVERSE statement?

Although on the surface of it, I think it's kind of clever, I get the distinct impression it runs poorly, and I also think it's not very readable from a support point of view.

Thoughts?.........

Marc
 
For those that do not have the Function reverse here's a binary search one.

IDENTIFICATION DIVISION.
PROGRAM-ID. "STRSIZE".
DATA DIVISION.
WORKING-STORAGE SECTION.
01 W01-MIN pic 9(4) BINARY.
01 W01-MAX pic 9(4) BINARY.
01 W01-MIDDLE pic 9(4) BINARY.
01 W01-STRING pic X(10).
01 W01-SIZE pic 9(4) BINARY.
PROCEDURE DIVISION.
MAIN.

MOVE ZERO TO W01-SIZE.
MOVE 1 TO W01-MIN.
MOVE LENGTH OF W01-STRING TO W01-MAX.
IF W01-STRING NOT = SPACES
PERFORM GET-SIZE
UNTIL W01-MIN > W01-MAX
END-IF.
COMPUTE W01-SIZE = W01-MIN - 1.
GOBACK.
GET-SIZE.
COMPUTE W01-MIDDLE = (W01-MIN + W01-MAX) / 2
IF W01-STRING(W01-MIDDLE:) = SPACES
COMPUTE W01-MAX = W01-MIDDLE - 1
ELSE
COMPUTE W01-MIN = W01-MIDDLE + 1
END-IF.
 
I am curious. How many CURRENT compilers have the

"LENGTH OF"

special register (used in the previous example) but do NOT have the REVERSE intrinsic function?

I know that IBM's VS COBOL II (long out of service) compiler was like this - but it seems ODD to me that there should be many compilers like that today. (Especially as "LENGTH OF" is an extension while FUNCITON REVERSE is standard)
 
Many old compilers have that. But "length of" in this discussion is about a substring.

It would be nice to give an extra option on the INSPECT statement with the keyword TRAILING instead of LEADING.

I still think the binairy search aproach using reference modification and testing for space will have a good performance. On the other hand: whom is making this string so unpredictable? It seems not smart to create such a problem.


 
Oops I was supposed to have removed that one.

That should be supplied by the programmer (Either hardcoded or in a called program if the programs is so changed).

But RM/COBOL and COBOL/400 (maybe not current, but still used a lot) do not have any of the intrinsic functions even though they have the "length of" register.

To Crox.
Performance with one particular brand of Windows COBOL compared to the following code
PERFORM VARYING W01-MAX FROM W01-MAX BY -1
UNTIL W01-MAX < 1
OR W01-STRING(W01-MAX:1) NOT = SPACES
CONTINUE
END-PERFORM.
is (in a P4 1.7 Windows 2k)
17 times faster for a 10000 bytes string,
12 times faster for a 1000 bytes string
3 times faster for a 100 bytes string

COBOL/400 is also pretty good but I don't have the timings.

As for Fujitsu v7, using function reverse timming is (compared to the binary search)
2 times slower for a 10000 bytes string.
1.5 times for a 1000 bytes string.
Negligible for a 100 bytes string

And hat do you mean with &quot;whom is making this string so unpredictable? It seems not smart to create such a problem&quot;

One of the projects I am working on at the moment as a requirement to process a string that varies from 20 bytes to 15000 bytes, and at all time I need to know the size of the string I'm working with!!

 
Hi,

The software that creates that string can perhaps also give you the length.

Example:

01 VARYSTRING.
03 VS-LENGTH PIC S9(4) COMP-5.
03 VS-CHAR OCCURS 1 TO 32767
DEPENDING ON VS-LENGTH
PIC X.

With COBOL 85 and higher, a move to varystring fills the VS-LENGTH first and the VS-CHAR part will be filled according to this length.

With COBOL 74 or less, you first have to move a length to VS-LENGTH before you do the move to varystring.

If the software that creates the string, also gives the length, you don't have to do all this processing to find the length because you have it. The system will be faster if it doesn't have to search every time perhaps even over and over again.

Regards,

Crox


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top