I was wondering how you could take 1 string, split it into 2 with a delimiter, such as space, and assign the 2 parts to 2 separate strings. I've tried using strtok()
but to no avail.

- 20,225
- 7
- 37
- 83

- 56,590
- 24
- 70
- 87
-
mostly because strings dont exist they are char arrays, you will find it difficult to split a string in C – Woot4Moo Mar 26 '10 at 13:19
-
10Show us your strtok() attempt. – Fred Larson Mar 26 '10 at 13:21
-
When you say, "I've tried using strtok(); but to no avail", why exactly didn't it work? What was the problem you ran into? – John Bode Mar 26 '10 at 13:21
-
Can you show your code using `strtok()`? – Naveen Mar 26 '10 at 13:21
-
Duplicate: http://stackoverflow.com/questions/2523624 – Paul R Mar 27 '10 at 20:01
8 Answers
#include <string.h>
char *token;
char line[] = "SEVERAL WORDS";
char *search = " ";
// Token will point to "SEVERAL".
token = strtok(line, search);
// Token will point to "WORDS".
token = strtok(NULL, search);
Update
Note that on some operating systems, strtok
man page mentions:
This interface is obsoleted by strsep(3).
An example with strsep
is shown below:
char* token;
char* string;
char* tofree;
string = strdup("abc,def,ghi");
if (string != NULL) {
tofree = string;
while ((token = strsep(&string, ",")) != NULL)
{
printf("%s\n", token);
}
free(tofree);
}
-
28`strtok()` modifies its input, so using it on a string literal is bad juju (a.k.a undefined behavior). – John Bode Mar 26 '10 at 13:23
-
-
@ereOn: Perhaps you missed the point. Your example is passing a pointer to a string literal, therefore strtok() will be modifying the string literal and invoking UB. – Fred Larson Mar 26 '10 at 13:34
-
My point was to demonstrate the basic use of strtok(). Well, I admit that using string literals in this situation is a bad pratice and should be avoided. Fun fact: if you look at http://www.cplusplus.com/reference/clibrary/cstring/strtok/ you can see the same "mistake" in the example. – ereOn Mar 26 '10 at 13:47
-
2I think if you change `char *line = "SEVERAL WORDS"` to `char line[] = "SEVERAL WORDS"`, you're all set. – Fred Larson Mar 26 '10 at 14:00
-
If this is true, I just learned something. I thought those two instructions had the same meaning. My bad. – ereOn Mar 26 '10 at 14:13
-
7@ereOn: Pointers and arrays are different things in C, until you sneeze near an array, and then it turns into a pointer. That's how the array size expression `sizeof(arr)/sizeof(arr[0])` works. – David Thornley Mar 26 '10 at 14:28
-
4
-
@ereOn Is it normal that strtok and strsep are throwing error signals ? Is there a way to avoid errors ? None of the code above worked without errors for me. – Bitterblue Jan 25 '13 at 08:49
-
@mini-me: I never heard of error signals using those functions. You probably should ask your own question (referring to this one, if it is relevant). – ereOn Jan 25 '13 at 09:18
For purposes such as this, I tend to use strtok_r() instead of strtok().
For example ...
int main (void) {
char str[128];
char *ptr;
strcpy (str, "123456 789asdf");
strtok_r (str, " ", &ptr);
printf ("'%s' '%s'\n", str, ptr);
return 0;
}
This will output ...
'123456' '789asdf'
If more delimiters are needed, then loop.
Hope this helps.

- 13,505
- 4
- 26
- 27
-
-
3strtok_r() is the reentrant version of strtok(). More about reentrancy here: http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29 – ereOn Mar 26 '10 at 15:55
char *line = strdup("user name"); // don't do char *line = "user name"; see Note
char *first_part = strtok(line, " "); //first_part points to "user"
char *sec_part = strtok(NULL, " "); //sec_part points to "name"
Note: strtok
modifies the string, so don't hand it a pointer to string literal.

- 12,418
- 6
- 43
- 61
You can use strtok() for that Example: it works for me
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
If you have a char array allocated you can simply put a '\0'
wherever you want.
Then point a new char * pointer to the location just after the newly inserted '\0'
.
This will destroy your original string though depending on where you put the '\0'

- 339,232
- 124
- 596
- 636
If you're open to changing the original string, you can simply replace the delimiter with \0
. The original pointer will point to the first string and the pointer to the character after the delimiter will point to the second string. The good thing is you can use both pointers at the same time without allocating any new string buffers.

- 414,610
- 91
- 852
- 789
-
Although I seem to understand the answer, a simple example would help a lot. For example, a beginner may ask: how to get both these pointers? – Peaceful Jun 21 '22 at 05:49
You can do:
char str[] ="Stackoverflow Serverfault";
char piece1[20] = ""
,piece2[20] = "";
char * p;
p = strtok (str," "); // call the strtok with str as 1st arg for the 1st time.
if (p != NULL) // check if we got a token.
{
strcpy(piece1,p); // save the token.
p = strtok (NULL, " "); // subsequent call should have NULL as 1st arg.
if (p != NULL) // check if we got a token.
strcpy(piece2,p); // save the token.
}
printf("%s :: %s\n",piece1,piece2); // prints Stackoverflow :: Serverfault
If you expect more than one token its better to call the 2nd and subsequent calls to strtok
in a while loop until the return value of strtok
becomes NULL
.

- 445,704
- 82
- 492
- 529
-
Looks good, except the second strtok() call is using a different delimiter. – John Bode Mar 26 '10 at 13:29
This is how you implement a strtok()
like function (taken from a BSD licensed string processing library for C, called zString).
Below function differs from the standard strtok()
in the way it recognizes consecutive delimiters, whereas the standard strtok()
does not.
char *zstring_strtok(char *str, const char *delim) {
static char *static_str=0; /* var to store last address */
int index=0, strlength=0; /* integers for indexes */
int found = 0; /* check if delim is found */
/* delimiter cannot be NULL
* if no more char left, return NULL as well
*/
if (delim==0 || (str == 0 && static_str == 0))
return 0;
if (str == 0)
str = static_str;
/* get length of string */
while(str[strlength])
strlength++;
/* find the first occurance of delim */
for (index=0;index<strlength;index++)
if (str[index]==delim[0]) {
found=1;
break;
}
/* if delim is not contained in str, return str */
if (!found) {
static_str = 0;
return str;
}
/* check for consecutive delimiters
*if first char is delim, return delim
*/
if (str[0]==delim[0]) {
static_str = (str + 1);
return (char *)delim;
}
/* terminate the string
* this assignmetn requires char[], so str has to
* be char[] rather than *char
*/
str[index] = '\0';
/* save the rest of the string */
if ((str + index + 1)!=0)
static_str = (str + index + 1);
else
static_str = 0;
return str;
}
Below is an example code that demonstrates the usage
Example Usage
char str[] = "A,B,,,C";
printf("1 %s\n",zstring_strtok(s,","));
printf("2 %s\n",zstring_strtok(NULL,","));
printf("3 %s\n",zstring_strtok(NULL,","));
printf("4 %s\n",zstring_strtok(NULL,","));
printf("5 %s\n",zstring_strtok(NULL,","));
printf("6 %s\n",zstring_strtok(NULL,","));
Example Output
1 A
2 B
3 ,
4 ,
5 C
6 (null)
You can even use a while loop (standard library's strtok()
would give the same result here)
char s[]="some text here;
do {
printf("%s\n",zstring_strtok(s," "));
} while(zstring_strtok(NULL," "));

- 1,181
- 1
- 14
- 24