-2

I was wondering, how am i able to split that kind of strings.

For example i have the following string: "80,8080,27001-27010,90"

I first want to split at the comma but if there is a minus in that substring i want to split it and get the difference between the two numbers by converting them via atoi(). The string i want to split is a list of ports, and i want to generate an array of integer with all ports enumerated. The strtok-function seems not suitable for this problem, is there any easy solution for this?

Using of strtok_r Example:

 substr1 = strtok_r(portlist, delim1, &saveptr1);
 while(substr1 != NULL){
    substr2 = strtok_r(substr1, delim2, &saveptr2);
    substr1 = strtok_r(NULL, delim2, &saveptr1);
 }
lt_katana
  • 148
  • 3
  • 12
  • `strtok-function seems not suitable`... please let us know why? – Sourav Ghosh Nov 19 '14 at 11:03
  • strtok saves the preparsed strings if i use strtok again for splitting the substring 27001-27010 i will loose the progress i previously made so i will not be able to parse the port 90. – lt_katana Nov 19 '14 at 11:12

2 Answers2

2

In your particular case, you can use strchr to find the point where to split a token, thereby avoiding losing the progress.

Another way is to use strtok_r, which is a reentrant version of strtok that doesn't have any internal state.

Edit:

strtok_r is not part of standard C. It is part of POSIX.1-2001. I think most major compilers support it. In Windows, the corresponding function is called strtok_s. A good way to make this portable is

#if defined(_WIN32) || defined(_WIN64)
/* We are on Windows */
# define strtok_r strtok_s
#endif

As described in Joachim Pileborgs answer to What's the difference between strtok_r and strtok_s in C?

Community
  • 1
  • 1
Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
  • So i have to create two save-pointers. One when i want to save the main progress and one to save the progress of the substring is that correct? I posted the example in the original question – lt_katana Nov 19 '14 at 11:24
  • Yes. You need a second loop to get all (both) values from the `strtok_r` on `delim2`. Also, the last strtok_r should use `delim1`. – Klas Lindbäck Nov 19 '14 at 11:30
  • Thanks you saved my day, i got really rusty in c programming – lt_katana Nov 19 '14 at 11:33
0

I prefer sscanf to parse strings in C

char *text =  "80,8080,,,27001-27010,+tt90";
int p[10];
int offset = 0, i = 0;
char bufDel[32], bufDigit[16];
while (sscanf(text+offset, "%[0-9]%[^0-9]", bufDigit, bufDel) != EOF) {
    offset += strlen(bufDigit) + strlen(bufDel);
    sscanf(bufDigit, "%d", &p[i]);
    ++i;
    bufDigit[0] = '\0';
    bufDel[0] = '\0';
}

%*[^0-9] reads all characters except digits 0-9 and throws them away. The output is 80 8080 27001 27010 90

Walter
  • 27
  • 1
  • 5
  • Problem is i need a dynamic solution that portlist can differ, the range can also be on another position so this would not work. – lt_katana Nov 19 '14 at 11:34
  • That is good and well if you have a fixed format. In this case I think the string is just an example and that the number of `,` and `-` is variable. – Klas Lindbäck Nov 19 '14 at 11:34
  • But thank you for sharing this, in fact that i am not able to use strtok_r for my programm, because of the given compiler config i have to parse my substring in a different way. – lt_katana Nov 19 '14 at 11:46
  • I assume you want to read integers from a string and the delimiers are non digits. The exact number of integers is unknown. Of course this is possible with sscanf, see edited program – Walter Nov 19 '14 at 19:24