将字符串分解为单词称为令牌化。strtok()
函数用于标记字符串。
它需要两个参数:要标记的字符串和包含所有可能的分隔符的字符串。
strtok_s()
比标准函数更安全。
因为它是可选的标准函数,所以需要将__STDC_WANT_LIB_EXT1__
符号定义为1
才能使用它。
strtok_s()
函数需要四个参数:
str
- 要标记化的字符串的地址,或者NULL
,对于第一个在同一个字符串之后的第二个和后续标记化操作的字符串。str_size
- 包含数组大小的整数变量的地址存储第一个参数。 这将由函数更新,在字符串中搜索的字符被标记化的数量。delimiters
- 包含所有标记分隔符的字符串的地址。pptr
- 指向char *
类型变量的指针,函数将在其中存储信息允许它在找到第一个令牌后继续搜索令牌。
示例代码
#define __STDC_WANT_LIB_EXT1__ 1 // Make optional versions of functions available
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
int main(void)
{
char delimiters[] = " ".,;:!?)("; // 分隔符
char buf[100]; // 用于键盘输入线的缓冲区
char str[1000]; // 存放被标记化字符串
char* ptr = NULL; // Pointer used by strtok_s()
str[0] = '\0'; // Set 1st character to null
size_t str_len = sizeof(str);
size_t buf_len = sizeof(buf);
printf("输入一些小于 %zd 字符的一段文字.\n 输入空行终止输入: \n", str_len);
// 从键盘上阅读多行散文
while (true)
{
if (!gets_s(buf, buf_len))// 阅读一行输入
{
printf("读取字符串出错.\n");
return 1;
}
if (!strnlen_s(buf, buf_len))// 空行结束输入
break;
if (strcat_s(str, str_len, buf)) // 将该行与`str`连接起来
{
printf("超出允许的最大输入长度.\n");
return 1;
}
}
printf("你输入的文字是: %s\n", str);
// 查找并列出文段中的所有单词
unsigned int word_count = 0;
char * pWord = strtok_s(str, delimiters, &ptr); // Find 1st word
if (pWord)
{
do
{
printf("%-18s", pWord);
if (++word_count % 5 == 0)
printf("\n");
pWord = strtok_s(NULL, delimiters, &ptr); //找到子字符
} while (pWord);// NULL ends tokenizing
printf("\n%u 字词找到.\n", word_count);
}
else
printf("字词未找到.\n");
return 0;
}