× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Hi Mark,

>  In RPG, this is ONE line of code!  The SCAN opcode allows an array in the
> result field.  The (numeric, no decimals) array will be populated with all
> the starting positions of the matches it finds.

But that only does part of the job.  It loads the positions of the
delimiters into an array -- which I guess is useful (??) but doesn't
extract the substrings from those positions.

I do agree with you that it's not hard to do.  In fact, that's why the
fact that strtok() keeps coming up on this list tends to completely puzzle
me.   Strtok() isn't even a good function -- and it's REALLY EASY to write
your own replacement for it.  So why on earth are people trying to use
strtok() in ILE RPG?

There's gotta be some book or article that tells people to use strtok() to
parse delimited fields or something that makes people keeping trying to
use it when there are so many better alternatives.

In many situations your SCAN solution will work -- but there are also
situations where it won't.  strtok(), strsep() and the gettok()
subprocedure that I posted all allow you to specify multiple delimiters.
That's not (easily) accomplished with SCAN or %scan().

Plus, the strtok(), strsep() and gettok() methods let you change
delimiters on each call -- which you COULD do with SCAN or %scan if you
called them in a loop, but not when you're returning an array.

>
>  UNFORTUNATELY (DCR time?), this feature is only valid in fixed format!
> But it may be worthwhile in order to avoid much more code.
>

I disagree.  If the only thing you wanted to do was store locations in an
array, then yes -- the SCAN op-code with an array output is a few lines
shorter.  But since you have to loop through the array to get any use of
the results, it doesn't save you antyhing.

Consider the following two programs.  One outputs to an array and loops
through it, the other uses the %scan() BIF.  Notice that it's the exact
same amount of code.  The only difference is that the actual scanning gets
moved into the loop:

     D string          s            100A
     D len             s             10I 0
     D x               s             10I 0
     D lastpos         s             10I 0
     D pos             s             10I 0 dim(50)
     D field           s             52A

1    c                   eval      string = 'Test||||||123|x|||8900'

2    c                   eval      lastpos = 1
3    c     '|'           scan      string        pos

4    c                   for       x = 1 to %elem(pos)

5    c                   if        pos(x) = 0
6    c                   leave
7    c                   endif

8    c                   eval      len = pos(x) - lastpos
9    c                   eval      field = %subst(string:lastpos:len)
10   c     field         dsply

11   c                   eval      lastpos = pos(x) + 1
12   c                   endfor

     c                   eval      *inlr = *on




     D string          s            100A
     D len             s             10I 0
     D lastpos         s             10I 0
     D pos             s             10I 0
     D field           s             52A

1    c                   eval      string = 'Test||||||123|x|||8900'
2    c                   eval      lastpos = 1

3    c                   dou       pos = 0

4    c                   eval      pos = %scan('|': string: lastpos)
5    c                   if        pos = 0
6    c                   leave
7    c                   endif

8    c                   eval      len = pos - lastpos
9    c                   eval      field = %subst(string:lastpos:len)
10   c     field         dsply

11   c                   eval      lastpos = pos + 1
12   c                   enddo

     c                   eval      *inlr = *on


By contrast, the gettok() subprocedure that I posted earlier is 11 lines
of code (not counting the D-specs, P-specs or /free, /end-free
statements -- which I didn't count above, either)  so it's actually
shorter.

Not only that, but it's reusable.  You can put it into a service program
and use it from anywhere.

And, when you call it from your own programs, you can do so in only one
line of code (assuming the output is an array) like this:

    field(*) = gettok(string : '|' : pos);

So, I guess I don't agree with you that SCAN is a better solution (though,
SCAN probably does perform better)

But a more important point, that I think we do agree on, is that it's easy
to do in RPG, and there are many different ways it can be done in RPG --
and all of them are better than strtok()!!


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 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.