String splitting function
Posted in 1995
By popular demand, here is the string splitting function that I use. Usage call split_string(src, delim, return, strict) returning stat, str1..strn src - Is string to split, max 5k delim - Field separator return - No. of strings to return (max). strict - Set status to -ve value if the no. of strings in src is not the same as return. Note: Get rid of any bugs yourself! Only kidding. Mark Denham BBC London, UK Mark.Denham@bbc.co.uk ----------------------------------- Cut here ---------------------------------------------- /* c source *} {************************************************************************* * * $Author$ * * $Date$ * * $Revision$ * * Doc Refs: * * Purpose: Allows an RDS program to split a string using a delimiter * given by the user. * * Usage: split_string string String to split. * delimiter Delimiter string. * returns Max no. of strings to return. * When there are less strings in * source than returns and strict is * FALSE, null strings are returned * for the remaining values. * strict If set causes the routine to return * a failure status if the number of * elements in string does not match * the number specified by returns. * * where: * * string char[5120] Null terminated string to split. * delimiter char[10] Null terminated delimiter string. * returns smallint Max. no. of strings to return. * strict integer TRUE/FALSE. Causes function to * fail when no. of strings found * does not match returns. * * Returns: stat integer 0 for ok, -ve as below: * -1 = Too few strings in source * -2 = retcnt > MAX_STRINGS * -3 = Source contains more strs * str[0..n] string As many strings as required. * * Library * Functions: * * Notes: WHEN USING RDS. * This function is MUST be linked with the RDS runner and debugger * using the cfglgo and cfgldb commands. Refer to the Interactive * debugger manual for details. * If you have a NULL value separated by 2 delimiters, * fred||john|... * This routine will not produce the result you expect! * * Modification Log *============================================================================ * * $Log$ * **************************************************************************** *} /* */ int dummy_string_split() { static char *rcsid = "@(#)$Header: $"; } #include <stdio.h> #include <stdlib.h> #define MAX_STRINGS 320 #define MAX_DELIM_LEN 10 #define MAX_STR_SIZE 5120 int split_string(numargs) int numargs; { char *strtok(); char src_string[MAX_STR_SIZE+1]; char delim[MAX_DELIM_LEN+1]; char *strlist[MAX_STRINGS]; char *nullstr = "", *str; int strict = 0, retcnt = 0, rval = 0, stat = 0, curridx = 0, idx = 0; if( numargs != 4 ) { /* This is a problem and cannot easily */ rval=-1; /* 4GL will most likely produce an error*/ retint(rval); /* indicating that the no. of returned */ return(1); /* values is incorrect....*/ } /* Read parameter list */ popint(&strict); popint(&retcnt); popvchar(delim, MAX_DELIM_LEN); popvchar(src_string, MAX_STR_SIZE); /* Check that the no. strings required does not exceed max allowed */ if( retcnt <= MAX_STRINGS ) { str = src_string; /* Split up string, fail if srtict and end of source string reached */ for(; curridx < retcnt; curridx++) { strlist[curridx] = strtok(str, delim); str = NULL; if( strict && strlist[curridx] == NULL ) { rval = -1; break; } } } else rval = -2; if( rval == 0 ) { if( strict ) { /* See if the source string is empty, if not fail */ if(strtok(str, delim) != NULL ) rval = -3; } } /* Return extraction status */ retint(rval); /* Return all filled in values, may help debugging when an error occurs */ for(idx=0; idx < curridx; idx++ ) { retvchar(strlist[idx]); } /* Now do rest of strings, if any */ while(idx < retcnt) { retvchar(nullstr); idx++; } return(idx+1); }