【C语言】strtok() - 切割字符串。

时间:2022-12-24 16:55:27

前言

在前面的文章 strlen()、strcpy()、strcat()、strcmp() 的四个字符串函数、这四个是最基本也是我们最常用的字符串函数、接下来我们要介绍的可能很多小伙伴比较陌生的字符串函数了,但是我们也是必须要认识的。例->

1.strstr() - 在一个字符串中查找另外一个字符串。

2.strtok() - 切割字符串。

3.strerror() - 返回错误码。

 ????strtok() - 切割字符串????

这个函数比较难懂,比较奇观,使用场景也不多见。

strtok() 函数的声明方式如下 ???? 

char * strtok ( char * str, const char * delimiters );

对该函数的调用序列将str分割成标记,标记是由连续字符组成的序列,由分隔符的任何字符分隔。 

在第一次调用时,函数期望一个C的字符串作为str的参数,它的第一个字符被用作扫描标记的起始位置。在随后的调用中,该函数期望得到一个空指针,并使用最后一个标记结束后的位置作为新的扫描起始位置。

要确定标记的开始和结束,函数首先从开始位置扫描分隔符中不包含的第一个字符(它成为标记的开始)。然后从标记的这个开头开始扫描分隔符中包含的第一个字符,这个字符成为标记的结尾。如果找到终止的空字符,扫描也会停止。

这个标记的末尾会被一个空字符自动替换,而该标记的开头则由函数返回。

一旦在strtok调用中找到str的终止空字符,所有后续对该函数的调用(以空指针作为第一个参数)都返回一个空指针。

找到最后一个令牌的位置由函数保存在内部,以便下次调用时使用(为了避免数据竞争,不需要特定的库实现)。

str→要截断的C字符串。注意,这个字符串被分解成更小的字符串(令牌)。
或者,可以指定一个空指针,在这种情况下,函数继续扫描之前对该函数的成功调用结束的地方。

delimiters→包含分隔符字符的C字符串。这些在不同的调用之间可能是不同的。

返回值:如果找到令牌,则指向令牌开头的指针。否则,为空指针。当被扫描的字符串到达字符串的末尾(即一个空字符)时,总是返回一个空指针。

????strtok()函数代码示例????

题目:把字符串"Hello.Cyuyan.yyds",.之前语句进行分割最后进行打印。用strtok字符串函数实现。

使用 strtok() 函数代码示例如下 ????

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

int main(void)
{
char str[] = "Hello.Cyuyan.yyds";
printf("yiduanhua|%s|dezifu\n", str);
char * pch=strtok(str, ".");
while (pch != NULL)
{
printf("%s\n", pch);
pch = strtok(NULL, ".");
}
return 0;
}

【C语言】strtok() - 切割字符串。

运行结果如下 ???? 

Hello.Cyuyan.yyds

Hello

Cyuyan

yyds

不知道你是否明白了( ゚д゚)つ

在这里思考下,那么它使用什么进行保存的呢?就是这个函数它能够记住地址,其实这个只需要用到一个关键字 static 静态局部变量就可以完美实现这种类似于记忆功能,把生命周期延长,出了函数的范围内不会销毁保留原来的值。

【C语言】strtok() - 切割字符串。


????strtok()源程序实现????

示例代码如下:????  

/***
*strtok.c - tokenize a string with given delimiters
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines strtok() - breaks string into series of token
* via repeated calls.
*
*******************************************************************************/

#include <cruntime.h>
#include <string.h>
#ifdef _SECURE_VERSION
#include <internal.h>
#else /* _SECURE_VERSION */
#include <mtdll.h>
#endif /* _SECURE_VERSION */

/***
*char *strtok(string, control) - tokenize string with delimiter in control
*
*Purpose:
* strtok considers the string to consist of a sequence of zero or more
* text tokens separated by spans of one or more control chars. the first
* call, with string specified, returns a pointer to the first char of the
* first token, and will write a null char into string immediately
* following the returned token. subsequent calls with zero for the first
* argument (string) will work thru the string until no tokens remain. the
* control string may be different from call to call. when no tokens remain
* in string a NULL pointer is returned. remember the control chars with a
* bit map, one bit per ascii char. the null char is always a control char.
*
*Entry:
* char *string - string to tokenize, or NULL to get next token
* char *control - string of characters to use as delimiters
*
*Exit:
* returns pointer to first token in string, or if string
* was NULL, to next token
* returns NULL when no more tokens remain.
*
*Uses:
*
*Exceptions:
*
*******************************************************************************/

#ifdef _SECURE_VERSION
#define _TOKEN *context
#else /* _SECURE_VERSION */
#define _TOKEN ptd->_token
#endif /* _SECURE_VERSION */

#ifdef _SECURE_VERSION
char * __cdecl strtok_s (
char * string,
const char * control,
char ** context
)
#else /* _SECURE_VERSION */
char * __cdecl strtok (
char * string,
const char * control
)
#endif /* _SECURE_VERSION */
{
unsigned char *str;
const unsigned char *ctrl = control;

unsigned char map[32];
int count;

#ifdef _SECURE_VERSION

/* validation section */
_VALIDATE_RETURN(context != NULL, EINVAL, NULL);
_VALIDATE_RETURN(string != NULL || *context != NULL, EINVAL, NULL);
_VALIDATE_RETURN(control != NULL, EINVAL, NULL);

/* no static storage is needed for the secure version */

#else /* _SECURE_VERSION */

_ptiddata ptd = _getptd();

#endif /* _SECURE_VERSION */

/* Clear control map */
for (count = 0; count < 32; count++)
map[count] = 0;

/* Set bits in delimiter table */
do {
map[*ctrl >> 3] |= (1 << (*ctrl & 7));
} while (*ctrl++);

/* Initialize str */

/* If string is NULL, set str to the saved
* pointer (i.e., continue breaking tokens out of the string
* from the last strtok call) */
if (string)
str = string;
else
str = _TOKEN;

/* Find beginning of token (skip over leading delimiters). Note that
* there is no token iff this loop sets str to point to the terminal
* null (*str == '\0') */
while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
str++;

string = str;

/* Find the end of the token. If it is not the end of the string,
* put a null there. */
for ( ; *str ; str++ )
if ( map[*str >> 3] & (1 << (*str & 7)) ) {
*str++ = '\0';
break;
}

/* Update nextoken (or the corresponding field in the per-thread data
* structure */
_TOKEN = str;

/* Determine if a token has been found. */
if ( string == str )
return NULL;
else
return string;
}

【C语言】strtok() - 切割字符串。

【C语言】strtok() - 切割字符串。


????strerror() - 返回错误码????