Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Double split in C

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!

like image 903
Dmitri Avatar asked Apr 10 '10 09:04

Dmitri


People also ask

What is split function in C?

In C, the strtok() function is used to split a string into a series of tokens based on a particular delimiter. A token is a substring extracted from the original string.

What is strtok function in C?

The C function strtok() is a string tokenization function that takes two arguments: an initial string to be parsed and a const -qualified character delimiter. It returns a pointer to the first character of a token or to a null pointer if there is no token.

Can you use strtok with multiple delimiters?

The function strtok breaks a string into a smaller strings, or tokens, using a set of delimiters. The string of delimiters may contain one or more delimiters and different delimiter strings may be used with each call to strtok .

How do you split a string?

The split() method splits a string into an array of substrings. The split() method returns the new array. The split() method does not change the original string. If (" ") is used as separator, the string is split between words.


3 Answers

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.

like image 119
Greg Hewgill Avatar answered Oct 01 '22 03:10

Greg Hewgill


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, ";,");
}
like image 31
N 1.1 Avatar answered Oct 01 '22 05:10

N 1.1


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);
}
like image 28
caf Avatar answered Oct 01 '22 05:10

caf