My input string is 1,2,3:4,5,6:7,5,8 First I need to split 1, 2, 3 set wit : delimiter. Then again I need to split 1 2 3 with , delimiter. So I need to do outer split and inner split till the end of input string.. Please explain me with some example
Asked
Active
Viewed 81 times
-7
-
`strtok`use it. – user2736738 Dec 28 '17 at 18:28
-
3Welcome to Stack Overflow! Kindly show your research / debugging effort so far. Please read [Ask] page first. – Sourav Ghosh Dec 28 '17 at 18:28
-
Here is a similar post you might find useful: https://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c – Junk junk Dec 28 '17 at 18:30
-
Second iteration strtok gives segments fault – Bhuvana Dec 28 '17 at 18:36
-
Using `strtok()` for this is a path to insanity if you are not careful. You can’t nest sequences of calls. You could split on colons and save each of three pointers, and then iterate over each of the saved pointers with commas. Are you only dealing with 3x3 splits, or could you have 20 colons and 1-30 commas in each? – Jonathan Leffler Dec 28 '17 at 18:40
-
"*need to split 1:2:3*": There is no "*1:2:3*" in your input. At least as per what you are writing. – alk Dec 28 '17 at 18:49
-
@JonathanLeffler if you need to nest `strtok`, then you should use `strtok_r` which is a reentrant version of `strtok`. Either way, you're right, you have to be careful with these functions. – Pablo Dec 28 '17 at 18:49
-
13 commas in each ( 13 fields in each set), but colons depends on the input received (not fixed) . Need to split the entire string into sets with : delimiter, then needs to split each set with , delimiter.. Each set have only 13 fields. So after splitting this 13 fields, need to put it in a structure. – Bhuvana Dec 28 '17 at 18:51
-
@Bhuvana you have 13 columns in total and where the `:` appears is random? On each line? Can you post two or three actual lines of your input? – Pablo Dec 28 '17 at 18:54
-
@Pablo: yes to `strtok_r()` on POSIX or`strtok_s()` on Windows. Or use `strcspn()` and maybe `strspn()`, or perhaps `strpbrk()`. These don’t mutilate the source string, so I prefer them (meaningful error reporting is easier, all else apart). – Jonathan Leffler Dec 28 '17 at 18:58
-
input string cintains some sets. Sets are separated by :delimiter, each set have 13 fields, these 13 fields are separated by , delimiter. First I need to extract set 1, then extract each fields of set, will put it in one structure. Then need to extract the set 2, then 13 fields of set 2... Similarly need to loop through the end of string – Bhuvana Dec 28 '17 at 19:03
-
Possible duplicate of [Split string with delimiters in C](https://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c) – dandan78 Dec 28 '17 at 19:18
-
@Bhuvana I've made an update of my example with nested `strtok`s. – Pablo Dec 28 '17 at 20:30
1 Answers
3
As coderredoc says, strtok
is the function you need.
#include <string.h>
char *strtok(char *str, const char *delim);
But strtok
have some
quirks you have to remember:
Only in the first call you have to pass the source (
str
), subsequent calls ofstrtok
must be passed withNULL
Strtok
modifies the source. Do not use unmodifiable strings or string literal ("this is a string literal"
)Because of the previous point, you should always do a copy of the source.
Simple example
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
const char *text = "Hello:World:!";
char *tmp = strdup(text);
if(tmp == NULL)
return 1; // no more memory
char *token = strtok(tmp, ":");
if(token == NULL)
{
free(tmp);
printf("No tokens\n");
return 1;
}
printf("Token: '%s'\n", token);
while(token = strtok(NULL, ":"))
printf("Token: '%s'\n", token);
free(tmp);
return 0;
}
Expected output
Token: 'Hello'
Token: 'World'
Token: '!'
Update
If you need to nest strtok
, you should use strtok_r
as mentioned before.
Here is an update of my example above. If I'm not mistaken, input
will have
the same format as yours (more or less, mine has different set sizes, but same principle)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
const char *input ="v1,v2,v3,v4,v5:w1,w2,w3,w4,w5:x1,x2,x3,x4:y1,y2,y3,y4,y5,y6";
char *input_copy = strdup(input);
char *set_track, *elem_track; // keep track for strtok_r
char *set, *value;
char *_input = input_copy;
int setnum = 0;
while(set = strtok_r(_input, ":", &set_track))
{
_input = NULL; // for subsequent calls of strtok_r
printf("Set %d contains: ", ++setnum);
// in this case I don't care about strtok messing with the input
char *_set_input = set; // same trick as above
while(value = strtok_r(_set_input, ",", &elem_track))
{
_set_input = NULL; // for subsequent calls of strtok_r
printf("%s, ", value);
}
puts("");
}
free(input_copy);
return 0;
}
Expected output
Set 1 contains: v1, v2, v3, v4, v5,
Set 2 contains: w1, w2, w3, w4, w5,
Set 3 contains: x1, x2, x3, x4,
Set 4 contains: y1, y2, y3, y4, y5, y6,

Pablo
- 13,271
- 4
- 39
- 59