C++ strtok()-为什么必须传递空指针才能获取字符串中的下一个标记?
这是strtok()的解释C++ strtok()-为什么必须传递空指针才能获取字符串中的下一个标记?,c++,c,string,pointers,strtok,C++,C,String,Pointers,Strtok,这是strtok()的解释 #包括 char*strtok(char*s1, 常量字符*s2)* 对strtok()的第一个调用返回指向 s1指向的字符串。对strtok()的后续调用必须传递NULL 指针作为第一个参数,以便在 绳子 但我不知道,为什么必须传递NULL指针才能获得字符串中的下一个标记。我搜索了大约15分钟,但在互联网上没有找到解释。如果传递非空值,则要求它开始标记不同的字符串 如果传递空值,则要求继续标记与以前相同的内容。strtok()使用静态变量将一些数据保存在自身内部。
#包括
char*strtok(char*s1,
常量字符*s2)*
对strtok()的第一个调用返回指向
s1指向的字符串。对strtok()的后续调用必须传递NULL
指针作为第一个参数,以便在
绳子
但我不知道,为什么必须传递NULL指针才能获得字符串中的下一个标记。我搜索了大约15分钟,但在互联网上没有找到解释。如果传递非空值,则要求它开始标记不同的字符串 如果传递空值,则要求继续标记与以前相同的内容。
strtok()
使用静态变量将一些数据保存在自身内部。这样,strtok()
就可以从上次调用时中断的位置继续搜索。要向strtok()发出持续搜索同一字符串的信号,请传递一个NULL
指针作为其第一个参数strtok()
检查第一个参数是否为NULL
,如果是,则使用当前存储的数据。如果第一个参数不为null,则将其视为新的搜索,并重置所有内部数据
也许您能做的最好的事情就是搜索strok()
函数的实际实现。我发现了一个足够小的参数,可以在这里发布,因此您可以了解如何处理此空参数:
/* Copyright (c) Microsoft Corporation. All rights reserved. */
#include <string.h>
/* ISO/IEC 9899 7.11.5.8 strtok. DEPRECATED.
* Split string into tokens, and return one at a time while retaining state
* internally.
*
* WARNING: Only one set of state is held and this means that the
* WARNING: function is not thread-safe nor safe for multiple uses within
* WARNING: one thread.
*
* NOTE: No library may call this function.
*/
char * __cdecl strtok(char *s1, const char *delimit)
{
static char *lastToken = NULL; /* UNSAFE SHARED STATE! */
char *tmp;
/* Skip leading delimiters if new string. */
if ( s1 == NULL ) {
s1 = lastToken;
if (s1 == NULL) /* End of story? */
return NULL;
} else {
s1 += strspn(s1, delimit);
}
/* Find end of segment */
tmp = strpbrk(s1, delimit);
if (tmp) {
/* Found another delimiter, split string and save state. */
*tmp = '\0';
lastToken = tmp + 1;
} else {
/* Last segment, remember that. */
lastToken = NULL;
}
return s1;
}
/*版权所有(c)微软公司。版权所有*/
#包括
/*ISO/IEC 9899 7.11.5.8标准。不赞成。
*将字符串拆分为标记,并在保留状态的同时一次返回一个标记
*内部。
*
*警告:仅保留一组状态,这意味着
*警告:函数不是线程安全的,也不能在中多次使用
*警告:一个线程。
*
*注意:任何库都不能调用此函数。
*/
char*\uuu cdecl strtok(char*s1,const char*divident)
{
静态char*lastToken=NULL;/*不安全的共享状态*/
char*tmp;
/*如果是新字符串,则跳过前导分隔符*/
如果(s1==NULL){
s1=最后一个令牌;
如果(s1==NULL)/*故事结束*/
返回NULL;
}否则{
s1+=strspn(s1,定界);
}
/*查找段的结尾*/
tmp=strpbrk(s1,定界);
如果(tmp){
/*找到另一个分隔符,拆分字符串并保存状态*/
*tmp='\0';
lastToken=tmp+1;
}否则{
/*最后一段,记住这一点*/
lastToken=NULL;
}
返回s1;
}
如果代码没有通过NULL
,那么代码应该通过什么来继续标记相同的字符串?我想这只是为了让您可以选择一次不标记整个字符串,而不跟踪下一个标记的起始位置。如果这是C++设计的,那么它很可能是不同的。你在搜索中没有看到它?Beaus,这是它40年前设计的方式。糟糕。单线程和单用途(不可嵌套),而不是提供上下文对象。我搜索的单词是“non-re-entrant”。但是,strtok怎么知道它是同一个字符串?现在传递NULL,但这不是字符串的地址。@ezph1,它一次只处理一个字符串,并保持内部状态,这会导致各种问题。非常感谢,现在我明白了!*警告:只保留一组状态,这意味着*WARNING:函数不是线程安全的,在*WARNING:一个线程内多次使用也不安全。这意味着什么?@MinhTran这意味着这个函数不应该在多线程调用中使用,因为静态变量可能会被其他线程更改。请参阅/*不安全共享状态*/代码>
/* Copyright (c) Microsoft Corporation. All rights reserved. */
#include <string.h>
/* ISO/IEC 9899 7.11.5.8 strtok. DEPRECATED.
* Split string into tokens, and return one at a time while retaining state
* internally.
*
* WARNING: Only one set of state is held and this means that the
* WARNING: function is not thread-safe nor safe for multiple uses within
* WARNING: one thread.
*
* NOTE: No library may call this function.
*/
char * __cdecl strtok(char *s1, const char *delimit)
{
static char *lastToken = NULL; /* UNSAFE SHARED STATE! */
char *tmp;
/* Skip leading delimiters if new string. */
if ( s1 == NULL ) {
s1 = lastToken;
if (s1 == NULL) /* End of story? */
return NULL;
} else {
s1 += strspn(s1, delimit);
}
/* Find end of segment */
tmp = strpbrk(s1, delimit);
if (tmp) {
/* Found another delimiter, split string and save state. */
*tmp = '\0';
lastToken = tmp + 1;
} else {
/* Last segment, remember that. */
lastToken = NULL;
}
return s1;
}