|
Hi Tim,
> I am using the strtok api and have used it many times. I seemed to
> have come across a situation that it is not working. I have a string
> that is has followed:
My advice to you: Never use strtok() in an RPG program. I'm not sure how
RPG programmers started using this API, but it's not a very good one, and
it really should be avoided.
strtok() has a lot of flaws, and even on Unix systems where delimited
strings are a way of life and C is the most popular programming language,
the strtok() function is discouraged because of it's flaws.
There's a function called strsep() that has all but replaced strtok() --
the only people still using strtok() are people who want maximum
portability, since it's part of the ISO C89 standard, it's available just
about everywhere -- but that's not an issue for an RPG programmer. Your
programs won't work on every version of Unix, anyway -- since most of them
don't support RPG at all.
> The problem is that the api seems to skip the delimiters that are
> stacked. This is throwing off my fields that are returned. I thought I
> would get back blanks for each field that has nothing between the
> delimiters.
No. Strtok() is clearly documented to skip over all consecutive
delimiters.
> Instead the api just seems to keep looking for data to
> return. Is there a way to prevent this or have the number of delimiters
> returned so I know how many fields to skip as well?
I don't understand why you're using strtok() at all. It would take, what,
15 minutes to write an equivalent routine in RPG? I mean, all strtok()
does is read each character in a string looking for a delimiter. That's
not exactly difficult to code.
Why not just write a routine that does the job, put it into a service
prgoram where you can call it from everywhere and be done with it?!
In fact, since it won't take any significant time, here... I'll write one
for you:
H DFTACTGRP(*NO)
D gettok PR 1024A varying
D string 65535A varying const options(*varsize)
D delims 50A varying const
D pos 10I 0
d blah s 100A varying
D tokens s 100A varying dim(50)
D x s 10I 0
D y s 10I 0
D msg s 52A
/free
Blah = 'Test||||||123|x|||8900';
x = 0;
y = 0;
//
// Get each token from the string and DSPLY it
//
dow ( x <= %len(blah) );
y = y + 1;
msg = 'token ' + %char(y) + '='
+ gettok( blah : '|' : x );
dsply msg;
enddo;
//
// Or, perhaps just dump all tokens to an array
//
x = 0;
tokens(*) = gettok( blah : '|' : x );
for y = 1 to %elem(tokens);
msg = 'elem ' + %char(y) + '=' + tokens(y);
dsply msg;
endfor;
*inlr = *on;
/end-free
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* gettok(): Get next token from string
*
* string = (input) string to search
* delims = (input) delimiters
* pos = (i/o) next position to search. At the start
* of a string, set this to zero. Pass
* it on subsequent calls to remember where
* you left off.
*
* Returns the token found.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P gettok B
D gettok PI 1024A varying
D string 65535A varying const options(*varsize)
D delims 50A varying const
D pos 10I 0
D res s 1024A varying
D start s 10I 0
D c s 1A
/free
start = pos + 1;
%len(res) = 0;
for pos = start to %len(string);
c = %subst(string:pos:1);
if %check(delims:c) = 1;
res = res + c;
else;
leave;
endif;
endfor;
return res;
/end-free
P E
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.