在以下C程序中,strtok
用于分割字符串。程序提供例外输出,但我无法理解它是如何工作的。
首先,我们已将字符串传递给tokenize 和分隔符。但是在以后的迭代中,我们只是传递NULL
。 如何和为什么功能会记住字符串?
如果我想同时将tokenize用于不同的字符串怎么办?
#include "stdafx.h"
#include <cstdio>
#include <cstring>
int main(int argc, char* argv[])
{
char arr[] = "This is string to split";
char * subStr = new char[10];
subStr = strtok(arr, " ");
while (subStr)
{
printf("%s\n", subStr);
subStr = strtok(NULL, " ");
}
return 0;
}
输出:
This
is
string
to
split
答案 0 :(得分:5)
strtok
函数有一个内部状态,可以记住它到达的最后一个位置。由于它通过将标记替换为零来覆盖原始字符串,因此需要记住的是字符串中的下一个位置。如果使用非空字符串参数调用strtok
,则内部状态将重置为新字符串。实际上,你不能一次在多个字符串上使用它,只能一个接一个地使用它。 (某些平台提供了可重入变量strtok_r
,允许您传递自己的状态变量。)
以下是一个示例实现:
char * my_strtok(char * in, char delim) // not quite the same signature
{
_Thread_local static char * pos = NULL;
if (in) { pos = in; }
char * p = find_next_delimiter(pos, delim); // NULL if not found
if (p) { *p = '\0'; ++p; pos = p; }
return p;
}
(真实的strtok
搜索给定列表的任何分隔符,并跳过空字段。)这个的可重入变体将用函数参数替换静态变量pos
。 p>
答案 1 :(得分:0)
strtok
函数使用静态变量来跟踪先前调用的状态。出于这个原因,它不是线程安全的(请查看strtok_r
)并且不应该使用它来同时标记不同线程上的不同字符串。
Here是可以实施的一种方式。
答案 2 :(得分:0)
“How”=使用静态变量。
“为什么”= for continue要求接下来的零,如果你再次传递原始字符串 - 你将需要再次跳过第一个令牌,松散的CPU周期
答案 3 :(得分:0)
strtok如何以及为何记住字符串?
strtok()
函数在解析时使用静态缓冲区。
如果我想同时将tokenize用于不同的字符串怎么办?
你可以建立自己的:
#include <stdio.h>
#include <string.h>
char *scan(char **pp, char c)
{
char *s = *pp, *p;
p = strchr(*pp, c);
if (p) *p++ = '\0';
*pp = p;
return s;
}
int main(void)
{
char s[] = "This is string to split";
char *p = s;
while (p) {
printf("%s\n", scan(&p, ' '));
}
return 0;
}
scan()
将原始字符串中\0
的所有分隔符替换为