c语言 strtok请教

这个函数返回的值是一个字符串指针,但当函数返回时,这个指针所指的字符串已经随函数执行完毕后被回收了,怎么会由函数的返回值得到字符串的呢?

以前我也被用字符串做参数和做返回值的函数该怎么写的问题困扰,我现在知道只要函数的任何一个参数被返回值所指,就能保证返回值所指的变量不会被回收(这样的返回值好象有点多余),但strtok函数的2个参数中的任何一个都和返回值所指的字符串不同,那么微软是如何实现,让函数返回的指针所指的字符串不被回收的呢?请大家给予指点!

我还做过实验,在第二次和以后调用strtok也就是把函数第一个参数设为NULL时,我用字符串指针数组分别保存strtok返回的指针,发现这些指针所指的内存地址都不同,到底是怎么实现的呢?

高手帮我解答一下吧,谢谢~
最新回答
苍山有井名为空

2025-03-28 00:07:23

恩, 虽然没有看过strtok的实现
不过下面这个, 即时效果应该相同的(每执行一次函数的效果); 测试代码是直接复制msdn里的, 我只写mytoken
(当然如果你原意给点分的话:p)

#include <stdio.h>

char* MyToken( char *strToken, const char *strDelimit );

int main( void )
{
char string[] = "A string\tof ,,tokens\nand some more tokens";
char seps[] = " ,\t\n";
char *token;

printf( "Tokens:\n" );

// Establish string and get the first token:
token = MyToken( string, seps ); // C4996
// Note: strtok is deprecated; consider using strtok_s instead
while( token != NULL )
{
// While there are tokens in "string"
printf( "%s\n", token );

// Get next token:
token = MyToken( NULL, seps ); // C4996
}
}
typedef int BOOL;
#define TRUE 1
#define FALSE 0

BOOL InSide( char c, const char *str )
{
while( 0 != *str )
if( c == *str )
return TRUE;
else
str++;
return FALSE;
}

char* MyToken( char *strToken, const char *strDelimit )
{
static char *strPoint = NULL;
char *strRet;
if( NULL != strToken )
strPoint = strToken;
if( NULL == strPoint )
return NULL;
while( 0 != *strPoint && InSide(*strPoint, strDelimit) )
*strPoint++ = 0;
if( 0 == *strPoint )
return strPoint = NULL;
strRet = strPoint;
while( 0 != *strPoint && !InSide(*strPoint, strDelimit) )
strPoint++;
if( 0 == *strPoint )
strPoint = NULL;
else
*strPoint++ = 0;
return strRet;
}
盛夏之末

2025-03-28 00:04:46

strtok每调用一次改写源串的一部分, 就是说每次把一个界定符置为'\0'
显然首次调用就直接将所以界定符置为'\0'更容易, 但作为提供给用户的库函数, 在调用的时候应该给外界带来最少的附加作用; 所以麻烦的只是底层的人咯

其实一句strtok(NULL," ?,");会有两个效果; 1是返回一个字串, 2是将字串末尾的界定符置为0; 也就是说其实strtok是有副作用的...

#include <string.h>
#include <stdio.h>

int main()
{
char str[] ="ab?#de?#g";
char *p;
//首先我想以'#'为界定符提取字串
//期望得到"ab?" "de?" "g"
p = strtok(str,"#");
while(p!=NULL) {
printf("%s\n", p);
p = strtok(NULL,"#");}
puts("");
//然后我又想以'?'为界定符, 期望得到"ab" "#de" "#g"
p = strtok(str,"?");
while(p!=NULL) {
printf("%s\n", p);
p = strtok(NULL,"?");}
//结果事与愿违
// ab?
// de?
// g
//
// ab

// strtok没有做到绝对方便用户
// 很有可能用户的一个串会多次使用
// 解决方法是用户再准备一个拷贝串
}