I have the following example for a Character 'g_temp' with an Array 'g_arr' :-
Define g_temp CHAR(1000),
Array g_arr OF RECORD
r_code char(3),
r_desc char(100),
r_date date
END RECORD
Main
Let g_temp = "<<<<1<<ABC<<<<2<<TESTING<<<<3<<10/MAY/2016<<<<1<<ZXY<<<<2<<LOOK AT THIS<<<<3<<31/AUG/2016<<<<1<<REG<<<<2<<NICE ONE<<<<3<<04/NOV/2016"
End Main
I would like to get some help in separating this variable contents as follow:
To place the first part of what is between <<<<1<< and <<<<2<< into g_arr. r_code [n]
To place the second part of what is between <<<<2<< and <<<<3<< into g_arr. r_desc [n]
To place the third part of what is between <<<<3<< and <<<<1<< into g_arr. r_date [n]
and so on
Which will end up the following results for our provided 'g_temp' example:
g_arr. r_code [1] = ABC
g_arr. r_desc [1] = TESTING
g_arr. r_date [1] = 10/MAY/2016
g_arr. r_code [2] = ZXY
g_arr. r_desc [2] = LOOK AT THIS
g_arr. r_date [2] = 31/AUG/2016
g_arr. r_code [3] = REG
g_arr. r_desc [3] = NICE ONE
g_arr. r_date [3] = 04/NOV/2016
Hi you can use the StringTokenizer to separate your string in a single-Column Array
and read this array in your array.
Maybe there is a easier way, but it works:
define g_temp string
define g_arr dynamic array of record
r_code char(3),
r_desc char(100),
r_date date
end record
define g_tmparray dynamic array of record
tmpfield string
end record,
g_tmpfield string
define g_token base.StringTokenizer,
g_z1 smallint,
g_z2 smallint,
g_z3 smallint
main
let g_temp = "<<<<1<<ABC<<<<2<<TESTING<<<<3<<10/MAY/2016<<<<1<<ZXY<<<<2<<LOOK AT THIS<<<<3<<31/AUG/2016<<<<1<<REG<<<<2<<NICE ONE<<<<3<<04/NOV/2016"
call g_arr.clear()
call g_tmparray.clear()
let g_z1 = 0
let g_z3 = 0
let g_token = base.StringTokenizer.create(g_temp, "<<<<")
while g_token.hasMoreTokens()
let g_tmpfield = g_token.nextToken()
case g_tmpfield --remove your "string counter" before inserted in the tmparray
when 1
continue while
when 2
continue while
when 3
continue while
end case
let g_z1 = g_z1 + 1
let g_tmparray[g_z1].tmpfield = g_tmpfield
end while
--show the tmparray
for g_z1 = 1 to g_tmparray.getLength()
display g_tmparray[g_z1].*
end for
--now build your g_arr from the tmparray
let g_z2 = 1
for g_z1 = 1 to g_tmparray.getLength()
if g_z2 = 1 then
let g_z2 = g_z2 + 1
let g_z3 = g_z3 + 1
let g_arr[g_z3].r_code = g_tmparray[g_z1].tmpfield
continue for
end if
if g_z2 = 2 then
let g_z2 = g_z2 + 1
let g_arr[g_z3].r_desc = g_tmparray[g_z1].tmpfield
continue for
end if
if g_z2 = 3 then
let g_z2 = 1 --imporant
let g_arr[g_z3].r_date = g_tmparray[g_z1].tmpfield
continue for
end if
end for
--result
for g_z1 = 1 to g_arr.getLength()
display g_arr[g_z1].r_code, " ", g_arr[g_z1].r_desc, " ", g_arr[g_z1].r_date
end for
end main
HTH Stefan
Thank you for your clear explanation ^_^
Quote from: Stefan S. on July 25, 2016, 08:46:40 AM
Hi you can use the StringTokenizer to separate your string in a single-Column Array
and read this array in your array.
Maybe there is a easier way, but it works:
define g_temp string
define g_arr dynamic array of record
r_code char(3),
r_desc char(100),
r_date date
end record
define g_tmparray dynamic array of record
tmpfield string
end record,
g_tmpfield string
define g_token base.StringTokenizer,
g_z1 smallint,
g_z2 smallint,
g_z3 smallint
main
let g_temp = "<<<<1<<ABC<<<<2<<TESTING<<<<3<<10/MAY/2016<<<<1<<ZXY<<<<2<<LOOK AT THIS<<<<3<<31/AUG/2016<<<<1<<REG<<<<2<<NICE ONE<<<<3<<04/NOV/2016"
call g_arr.clear()
call g_tmparray.clear()
let g_z1 = 0
let g_z3 = 0
let g_token = base.StringTokenizer.create(g_temp, "<<<<")
while g_token.hasMoreTokens()
let g_tmpfield = g_token.nextToken()
case g_tmpfield --remove your "string counter" before inserted in the tmparray
when 1
continue while
when 2
continue while
when 3
continue while
end case
let g_z1 = g_z1 + 1
let g_tmparray[g_z1].tmpfield = g_tmpfield
end while
--show the tmparray
for g_z1 = 1 to g_tmparray.getLength()
display g_tmparray[g_z1].*
end for
--now build your g_arr from the tmparray
let g_z2 = 1
for g_z1 = 1 to g_tmparray.getLength()
if g_z2 = 1 then
let g_z2 = g_z2 + 1
let g_z3 = g_z3 + 1
let g_arr[g_z3].r_code = g_tmparray[g_z1].tmpfield
continue for
end if
if g_z2 = 2 then
let g_z2 = g_z2 + 1
let g_arr[g_z3].r_desc = g_tmparray[g_z1].tmpfield
continue for
end if
if g_z2 = 3 then
let g_z2 = 1 --imporant
let g_arr[g_z3].r_date = g_tmparray[g_z1].tmpfield
continue for
end if
end for
--result
for g_z1 = 1 to g_arr.getLength()
display g_arr[g_z1].r_code, " ", g_arr[g_z1].r_desc, " ", g_arr[g_z1].r_date
end for
end main
HTH Stefan
I am not sure if stringTokenizor http://4js.com/online_documentation/fjs-fgl-manual-html/#c_fgl_ClassStringTokenizer.html is the best here. It is designed for cases where the delimiter is constant between fields such as the case with CSV or Informix unload files.
So if you had "," as the delimiter, then you would have something like ...
Define g_temp CHAR(1000),
Array g_arr OF RECORD
r_code char(3),
r_desc char(100),
r_date date
END RECORD
DEFINE tok base.StringTokenizer
DEFINE idx INTEGER
Main
Let g_temp = "ABC,TESTING,10/MAY/2016,ZXY,LOOK AT THIS,31/AUG/2016,REG,NICE ONE,04/NOV/2016"
LET tok = base.StringTokenizer.create(g_temp,",")
LET idx = 0
WHILE tok.hasMoreTokens()
LET idx = idx + 1
LET g_arr[idx].r_code = tok.nextToken()
LET g_arr[idx].r_desc = tok.nextToken()
LET g_arr[idx].r_date = tok.nextToken()
WHILE
End Main
If the delimiter between each field was different as in your example, I'd be using base.String methods http://4js.com/online_documentation/fjs-fgl-manual-html/#c_fgl_datatypes_STRING_methods.html
Define g_temp STRING,
Array g_arr OF RECORD
r_code char(3),
r_desc char(100),
r_date date
END RECORD
DEFINE idx INTEGER
DEFINE pos1a, pos2,pos3,pos1b INTEGER
Main
Let g_temp = "<<<<1<<ABC<<<<2<<TESTING<<<<3<<10/MAY/2016<<<<1<<ZXY<<<<2<<LOOK AT THIS<<<<3<<31/AUG/2016<<<<1<<REG<<<<2<<NICE ONE<<<<3<<04/NOV/2016"
LET idx = 0
WHILE TRUE
LET pos1a = g_temp.getIndexOf("<<<<1<<",1)
LET pos2 = g_temp.getIndexOf("<<<<2<<",pos1)
LET pos3 = g_temp.getIndexOf("<<<<3<<",pos2)
LET pos1b = g_temp.getIndexOf("<<<<1<<",pos3)
IF pos1b = 0 THEN -- End of file
LET pos1b = g_temp.getLength()+1
END IF
LET idx = idx + 1
LET g_arr[idx].r_code = g_temp.subString(pos1a+7,pos2-1)
LET g_arr[idx].r_desc = g_temp.subString(pos2+7,pos3-1)
LET g_arr[idx].r_date = g_temp.subString(pos3+7,pos1b-1)
LET g_temp = g_temp.subString(pos1b, g_temp.getLength())
IF g_temp.getLength() = 0 THEN
EXIT WHILE
END IF
END WHILE
End Main
... you will need to add some additional code to handle cases where pos1,pos2,pos3 are zero, (and you should double check my maths) but the important thing is for you to see the base.String methods getIndexOf and subString.
Reuben