Double split in C
Asked Answered
W

5

7

OK. For example I have this line in my txt file:

1|1,12;7,19;6,4;8,19;2,2
As you can see, it has 2 parts, separated by |. I have no problems getting both parts, and separating second part 1,12;7,19;6,4;8,19;2,2 using ; separator. BUT I do have problems with separating further by , to get first and second number of each set.

This is my current code:

  result = strtok(result, ";");

  while(result != NULL ) {
      printf("%s\n", result);
      result = strtok(NULL, ";");
  }

It outputs me:

1,12
7,19
6,4
8,19
2,2

OK, great. But when I try to 'strtok' (I'm using this method for splitting) like this:

 result = strtok(result, ";");

 while(result != NULL ) {
     //printf("%s\n", result);
     help    = strtok(result, ",");    
     while(help != NULL) {
         printf("<%s>", help);
         help = strtok(NULL, ",");
     }

     result  = strtok(NULL, ";");
 }

I only get "<1>,<12>" like there is only one set in this set of numbers. I dont understand where are the rest of the numbers. Instead, output should be: <1>,<12>,<7>,<19>,<6>,<4>,<8>,<19>,<2>,<2>. Could someone please give a solution, how to get EACH number of each set this set of numbers. Maybe there are other methods or I'm doing something wrong :)

Thank you!

Weekly answered 10/4, 2010 at 9:39 Comment(0)
H
3

char *strtok(char *str, const char *delim); (from man pages)
The delim argument specifies a set of characters that delimit the tokens in the parsed string. The caller may specify different strings in delim in successive calls that parse the same string.

So, use both ; and , as delimiter to get all the numbers.

//this will delimit result whenever ";" or "," is found
result = strtok(result, ";,"); 

while(result != NULL ) {
    printf("%s\n", result);
    result = strtok(NULL, ";,");
}
Historied answered 10/4, 2010 at 9:43 Comment(0)
C
6

In addition to what Neil pointed out regarding modifying the original string, the strtok() function is not designed to be used in a nested manner like you describe. You may wish to investigate the strtok_r() function, or avoid the use of the strtok* family altogether.

Chesterton answered 10/4, 2010 at 9:45 Comment(0)
H
3

char *strtok(char *str, const char *delim); (from man pages)
The delim argument specifies a set of characters that delimit the tokens in the parsed string. The caller may specify different strings in delim in successive calls that parse the same string.

So, use both ; and , as delimiter to get all the numbers.

//this will delimit result whenever ";" or "," is found
result = strtok(result, ";,"); 

while(result != NULL ) {
    printf("%s\n", result);
    result = strtok(NULL, ";,");
}
Historied answered 10/4, 2010 at 9:43 Comment(0)
D
2

As others have pointed out, strtok() isn't reentrant - it maintains internal state about the string it's parsing, so it can't be used to parse two different strings simultaneously (which means two different non-NULL values for its first argument, so your situation counts).

If you have the reentrant version strtok_r() available, you can change your code to use it like so:

char *st_result, *st_help;
result = strtok_r(result, ";", &st_result);

while (result) {
     printf("[%s]", result);
     help = strtok_r(result, ",", &st_help);    
     while (help) {
         printf("<%s>", help);
         help = strtok_r(NULL, ",", &st_help);
     }

     result = strtok_r(NULL, ";", &st_result);
}
Doncaster answered 10/4, 2010 at 12:12 Comment(0)
M
1

The first strtok splits the original into several null terminated strings. The second strtok is only applied to the first of these strings - it stops at the first null-terminator created by the first strtok call. You need to call the second strtok code for EACH of the strings created by the first.

Minestrone answered 10/4, 2010 at 9:43 Comment(0)
R
1

C's strtok is pretty evil in that it modifies the source string, inserting NULL in place of your separator. Thus your second loop stops when it reaches the NULL inserted by the outer loop. What you want is to save the pointers to your ;-separated strings somewhere else, and then strtok each of them separately.

Or, if you do want to use nested loops, see here.

Relegate answered 10/4, 2010 at 9:48 Comment(1)
Wow. Thanks guys! Works great! Never thought it was so simple.Weekly

© 2022 - 2024 — McMap. All rights reserved.