在C语言中使用strtok()和strtok_r()函数
在本文中,我们将介绍如何在C语言中使用strtok()和strtok_r()函数。
如果要标记字符串,这些功能非常有用。
C提供了这些方便的实用程序函数,可将我们的输入字符串拆分为标记。
让我们通过适当的示例来看看如何使用这些功能。
使用strtok()函数
首先,让我们看一下strtok()函数。
该函数是<string.h>头文件的一部分,因此必须在程序中包含它。
#include <string.h> char* strtok(char* str, const char* delim);
这将接受输入字符串str
和分隔符delim
。
strtok()会根据定界字符将字符串拆分为标记。
我们期望来自strtok()
的字符串列表。
但是该函数返回一个字符串!为什么是这样?
原因是该函数如何处理标记化。
调用strtok(input,delim)
之后,它返回第一个令牌。
但是我们必须继续在输入为NULL的字符串上反复调用该函数,直到得到NULL!
基本上,我们需要继续调用strtok(NULL,delim)
,直到它返回NULL
。
似乎令人困惑?让我们看一个例子来清除它!
#include <stdio.h> #include <string.h> int main() { //Our input string char input_string[] = "Hello from theitroad!"; //Our output token list char token_list[20][20]; //We call strtok(input, delim) to get our first token //Notice the double quotes on delim! It is still a char* single character string! char* token = strtok(input_string, " "); int num_tokens = 0; //Index to token list. We will append to the list while (token != NULL) { //Keep getting tokens until we receive NULL from strtok() strcpy(token_list[num_tokens], token); //Copy to token list num_tokens++; token = strtok(NULL, " "); //Get the next token. Notice that input=NULL now! } //Print the list of tokens printf("Token List:\n"); for (int i=0; i < num_tokens; i++) { printf("%s\n", token_list[i]); } return 0; }
因此,我们有输入字符串" Hello from theitroad!",我们正在尝试用空格标记它。
我们使用`strtok(input,"")"获得第一个令牌。
请注意双引号,因为分隔符是单个字符串!
之后,我们继续使用strtok(NULL,"")"获得令牌并循环,直到从
strtok()获得
NULL`。
现在来看一下输出。
输出
Token List: Hello from theitroad!
实际上,我们似乎已经获得了正确的令牌!
同样,现在让我们看看使用strtok_r()
。
使用strtok_r()函数
这个函数与strtok()
函数非常相似。
关键区别在于_r
表示这是一个可重入函数。
可重入函数是可以在其执行期间中断的函数。
也可以再次安全地调用此类函数,以恢复执行!
这就是为什么它是"可重入"功能的原因。
只是因为它可以安全地再次进入!
因此,重入函数是线程安全的,这意味着它们可以安全地被线程中断,因为它们可以再次恢复而不会造成任何伤害。
现在,类似于strtok()
,strtok_r()
函数是它的线程安全版本。
但是,这有一个另外的参数,称为上下文。
我们需要这样做,以便函数可以从正确的位置恢复。
注意:如果您使用的是Windows,则等效功能为strtok_s()。
strtok_r()适用于基于Linux/Mac的系统!
#include <string.h> char *strtok_r(char *str, const char *delim, char **context);
参数" context"是指向字符的指针," strtok_r"在内部用于保存其状态。
通常,我们可以从用户声明的指针传递它。
让我们看一下" strtok()"的相同示例,现在使用" strtok_r()"(或者Windows上的" strtok_s()")。
#include <stdio.h> #include <string.h> int main() { //Our input string char input_string[] = "Hello from theitroad!"; //Our output token list char token_list[20][20]; //A pointer, which we will be used as the context variable //Initially, we will set it to NULL char* context = NULL; //To get the value of the context variable, we can pass it's address //strtok_r() to automatically populate this context variable, and refer //it's context in the future char* token = strtok_r(input_string, " ", &context); int num_tokens = 0; //Index to token list. We will append to the list while (token != NULL) { //Keep getting tokens until we receive NULL from strtok() strcpy(token_list[num_tokens], token); //Copy to token list num_tokens++; token = strtok_r(NULL, " ", &context); //We pass the context variable to strtok_r } //Print the list of tokens printf("Token List:\n"); for (int i=0; i < num_tokens; i++) { printf("%s\n", token_list[i]); } return 0; }
输出
Token List: Hello from theitroad!
虽然我们得到相同的输出,但是此版本更好,因为它是线程安全的!