*********************************/
/******************************************************************************
The program below uses nested loops that employ strtok_r() to break a
string into a two-level hierarchy of tokens. The first command-line
argument specifies the string to be parsed. The second argument speci‐
fies the delimiter character(s) to be used to separate that string into
"major" tokens. The third argument specifies the delimiter charac‐
ter(s) to be used to separate the "major" tokens into subtokens.
An example of the output produced by this program is the following:
$ ./a.out 'a/bbb///cc;xxx:yyy:' ':;' '/'
1: a/bbb///cc
--> a
--> bbb
--> cc
2: xxx
--> xxx
3: yyy
--> yyy
1: a/bbb///cc
--> a
--> bbb
--> cc
2: xxx
--> xxx
3: yyy
--> yyy
*******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * strtok_r1(char *str, const char *delim, char **saveptr)
{
char *p = NULL;
char *pd = NULL;
char flag = 0;
if (str != NULL)
{
*saveptr = str;
}
/* ignore the start delimeter of the token in the str */
pd = (char *)delim;
while (*pd != '\0')
{
if (*pd == **saveptr)
{
(*saveptr)++; // note: here use *saveptr++ is wrong!
pd = (char *)delim;
}
else
{
pd++;
}
}
p = *saveptr;
/* find the token in the str */
while (**saveptr!= '\0')
{
pd = (char *)delim;
while ((*pd != '\0') && (*pd != **saveptr))
{
pd ++;
}
if (*pd == **saveptr)
{
**saveptr = '\0';
(*saveptr)++; // note: here use *saveptr++ is wrong!
return p;
}
else
{
flag = 1;
(*saveptr)++; // note: here use *saveptr++ is wrong!
}
}
if (('\0' == **saveptr) && !flag)
{
*saveptr = NULL;
return *saveptr;
}
return p;
}
int main(int argc, char *argv[])
{
char *str1, *str2, *token, *subtoken;
char *saveptr1, *saveptr2;
int j;
char arg1[] = "a/bbb///cc;xxx:yyy:";
char arg2[] = ":;";
char arg3[] = "/";
if (argc != 4)
{
fprintf(stderr, "Usage: %s string delim subdelim\n",
argv[0]);
exit(EXIT_FAILURE);
}
for (j = 1, str1 = argv[1]; ; j++, str1 = NULL)
{
token = strtok_r(str1, argv[2], &saveptr1);
if (token == NULL)
break;
printf("%d: %s\n", j, token);
for (str2 = token; ; str2 = NULL)
{
subtoken = strtok_r(str2, argv[3], &saveptr2);
if (subtoken == NULL)
break;
printf(" --> %s\n", subtoken);
}
}
putchar('\n');
for (j = 1, str1 = arg1; ; j++, str1 = NULL)
{
token = strtok_r1(str1, arg2, &saveptr1);
if (token == NULL)
break;
printf("%d: %s\n", j, token);
for (str2 = token; ; str2 = NULL)
{
subtoken = strtok_r1(str2, arg3, &saveptr2);
if (subtoken == NULL)
break;
printf(" --> %s\n", subtoken);
}
}
exit(EXIT_SUCCESS);
}