在C语言中按空格分割字符串

10

我正在使用C语言,通过套接字将接收一个带有一个空格的消息,我需要在空格处将字符串分成多个部分。我该如何操作?


我在另一篇帖子中回答了这个问题这里 - Sam Petrocelli
3个回答

16

strtok_r 是你的好朋友。

不要使用普通的 strtok(),因为它不是线程安全的。

即使在支持线程安全的平台上(因为状态保存在线程本地存储中),仍然存在一个问题,即使用内部状态意味着不能同时从几个字符串中解析标记。

例如,如果你编写一个函数来使用 strtok() 分离字符串 A,那么你的函数就不能在另一个使用 strtok() 来分割字符串 B 的函数的循环内被调用。


这可能在某些平台上是这样,但在MSVC中并非如此。strtok是线程安全的,传统上使用静态存储的各种其他CRT函数也是如此。 - Will Dean
@Will - 更新了。如果我理解正确,它使用TLS的方式意味着你不能同时将两个字符串进行strtok处理... - Roddy

6
如果您拥有字符串缓冲区,并且知道可以安全修改它,您可以使用像人们建议的 strtok_r()。或者您可以自己这样做:
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'.
}

这可能会更快,更易于理解,具体情况取决于上下文。

0

通常使用strtok()库调用来完成此操作。但请注意,此函数将修改输入字符串(它在选择的分隔符处插入'\0' NUL字符),因此如果您需要稍后访问整个字符串,则可能需要在字符串的副本上调用strtok()。

编辑:正如另一位帖子所提到的那样,“普通”的strtok()不是线程安全的,因此调用strtok_r()是更安全的函数。我不确定strtok_r()是否存在相同的问题,即原地修改输入缓冲区。


strtok_r是一个Posix函数,但它可能在Windows上不可用。 - Johannes Schaub - litb
Microsoft 的 strtok 函数自从我能记起来以来就是线程安全的了。其中的 'static' 数据实际上存储在线程本地存储中。 - Will Dean
1
strtok() 在 MS 上可能是线程安全的,但它不是可重入的;一次只能有一个代码位使用它。也就是说,您不能让 FunctionA() 使用 strtok() 解析字符串,并调用 FunctionB(),其中 FunctionB() 也调用 strtok() 来解析另一个字符串。FunctionA() 现在出问题了! - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接