tags:

views:

1479

answers:

3

I'm working with C and through a socket I will be receiving a message with one space in it, I need to split the string into parts at the space. How would I go about doing this?

+8  A: 

strtok_r is your friend.

Don't use plain strtok, as it's NOT thread-safe.

Even on platforms where it is thread-safe (because the state is held in Thread-Local Storage), there is still the problem that the use of internal state means you cannot parse tokens from several strings simultanesously.

for example, if you write a function which uses strtok() to separate string A, your function cannot be called within the loop of a second function which is using strtok() to split string B.

Roddy
This may be the case on some platforms but is not the case with MSVC. strtok is thread-safe, as are the various other CRT functions which have traditionally used static storage.
Will Dean
@Will - updated. If I have it right, its use of TLS still means you can't be simultaneously strtokking two strings...
Roddy
A: 

This is usually done using the strtok() library call. Be warned, however, that this function will modify the input string (it inserts '\0' NUL characters everywhere that the chosen delimiter was found) - so you may want to call strtok() on a copy of the string if you need to access the whole thing later.

EDIT: as mentioned by another poster, "plain" strtok() isn't thread-safe, so strtok_r() is the safer function to call. I'm not sure whether strtok_r() has the same problem of modifying the input buffer in-place.

Matt Campbell
strtok_r is, however a Posix function. it may not be available on windows.
Johannes Schaub - litb
Microsoft strtok *is* thread safe and has been for as long as I can remember. The 'static' data is actually held in thread-local storage.
Will Dean
strtok() on MS may be thread-safe, but it is not re-entrant; only one bit of code may use it at a time. That is, you cannot have FunctionA() using strtok() to parse a string, and have it call FunctionB() where FunctionB() also calls strtok() to parse a different string. FunctionA() is now screwed!
Jonathan Leffler
+2  A: 

If you own the string buffer, and know that it is safe to modify, you can use strtok_r() as people have suggested. Or you could do it yourself, like this:

char buffer[2048];
char *sp;

/* read packet into buffer here, omitted */

/* now find that space. */
sp = strchr(buffer, ' ');
if(sp != NULL)
{
  /* 0-terminate the first part, by replacing the space with a '\0'. */
  *sp++ = '\0';
  /* at this point we have the first part in 'buffer', the second at 'sp'.
}

This might be faster and/or easier to understand, depending on context.

unwind