How to store multiple character positions in a string inside an array in free RPGLE format?

In standard RPGLE my code looks like this. This statement stores comma positions in Data in the ComArr array .

C     ','           Scan      Data          ComArr  

      

I've tried doing it in free format. But all indices of the ComArr array are loaded with the first comma in the Data . This is because% Scan returns only one position and when saving it to an array, it ends loading the entire array with a single value.

ComArr = %Scan(',':Data) ;

      

Is there any other way to handle SCAN in RPG format like in C spec? Basically I want to split a delimited string.

+3


source to share


2 answers


One possibility is to keep the C-spec as it is. If a block of code needs an array of separator positions, and one line of code already does so, comment above the fixed format specification describing what it does and leave it there.

If / free is required and you don't want to replace the entire block of code, you will need to roll your own loop to build the delimiter array.



I personally don't convert from fixed to / for free unless I rewrite the block of code to be functionally different. That is, I would almost certainly write a different algorithm in / for free than I would write in a revised form. So the whole process of building an array of separator positions and then splitting a string based on that array is not something I would do in / free.

I would write a new subroutine that returns an array of strings with a single delimited input string. The code inside this subroutine will run one pass through the input, looking for delimiters with% scan (), and for each one found, split the substring by the next available element in the output array. No need for an array of dividing positions with such an algorithm.

+2


source


This is probably a little late, but if anyone else needs to split the string on a specific subject, this code should do what you need.

If you assign a value to an array using a wildcard eval array(*) = ...

, it applies to all elements in the array.

Declare a prototype in your source:

D split           pr          1024a   varying                     
D  string                    65535a   varying const options(*varsize)
D  delims                       50a   varying const               
D  pos                          10i 0

      

Declare a couple of variables. This assumes your input line is 1000 characters and each individual element has a maximum of 10 characters:

D idx             s             10i 0
D list            s           1000a
D splitAry        s             10a   dim(100)

      



This is how you split the string. This tells you that your delimeter is a comma:

c                   eval      idx = 0                          
c                   eval      splitAry(*) = split(list:',':idx)

      

Define a procedure that does the job:

 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * split - Split delimited string                                      
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Psplit            b                   export                           
D split           pi          1024a   varying                          
D  iString                   65535a   varying const options(*varsize)  
D  iDelims                      50a   varying const                    
D  iPos                         10i 0                                  
 *                                                                     
D result          s           1024a   varying                          
D start           s             10i 0                                  
D char            s              1a                                    
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
c                   eval      start = iPos + 1                         
c                   eval      %len(result) = 0                         
 *                                                                     
c                   for       iPos = start to %len(iString)            
c                   eval      char = %subst(iString:iPos:1)            
c                   if        %check(iDelims:char) = 1                 
c                   eval      result = result + char                   
c                   else                                               
c                   leave                                              
c                   endif                                              
c                   endfor                                             
 *                                                                     
c                   return    result                                   
Psplit            e     

      

Don't forget to add dftactgrp (* no) to your H spec if you define and use this in the same module!

0


source







All Articles