c语言中strtok函数
In this article, we’ll take a look at using the strtok() and strtok_r() functions in C.
在本文中,我们将介绍如何在C语言中使用strtok()和strtok_r()函数。
These functions are very useful, if you want to tokenize a string. C provides these handy utility functions to split our input string into tokens.
如果要标记字符串,这些功能非常有用。 C提供了这些方便的实用程序函数,可将我们的输入字符串拆分为标记。
Let’s take a look at using these functions, using suitable examples.
让我们使用合适的示例来看看如何使用这些功能。
使用strtok()函数 (Using the strtok() function)
First, let’s look at the strtok() function.
首先,让我们看一下strtok()函数。
This function is a part of the <string.h>
header file, so you must include it in your program.
此函数是<string.h>
头文件的一部分,因此必须在程序中包含它。
#include <string.h>
char* strtok(char* str, const char* delim);
This takes in an input string str
and a delimiter character delim
.
这将接受输入字符串str
和定界符delim
。
strtok()
will split the string into tokens based on the delimited character.
strtok()
将根据定界字符将字符串拆分为标记。
We expect a list of strings from strtok()
. But the function returns us a single string! Why is this?
我们期望从strtok()
获得字符串列表。 但是该函数返回一个字符串! 为什么是这样?
The reason is how the function handles the tokenization. After calling strtok(input, delim)
, it returns the first token.
原因是该函数如何处理标记化。 调用strtok(input, delim)
,它返回第一个标记。
But we must keep calling the function again and again on a NULL
input string, until we get NULL
!
但是我们必须继续在NULL
输入字符串上一次又一次地调用该函数,直到获得NULL
为止!
Basically, we need to keep calling strtok(NULL, delim)
until it returns NULL
.
基本上,我们需要继续调用strtok(NULL, delim)
直到返回NULL
。
Seems confusing? Let’s look at an example to clear it out!
似乎令人困惑? 让我们看一个例子来清除它!
#include <stdio.h>
#include <string.h>
int main() {
// Our input string
char input_string[] = "Hello from JournalDev!";
// 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;
}
So, we have our input string “Hello from JournalDev!”, and we’re trying to tokenize it by spaces.
因此,我们有输入字符串“ Hello from JournalDev!”,我们正在尝试用空格标记它。
We get the first token using strtok(input, " ")
. Notice the double quotes, as the delimiter is a single character string!
我们使用strtok(input, " ")
获得第一个令牌。 注意双引号,因为定界符是单个字符串!
Afterwards, we keep getting tokens using strtok(NULL, " ")
and loop until we get NULL
from strtok()
.
之后,我们继续使用strtok(NULL, " ")
获取令牌并循环,直到从strtok()
获取NULL
。
Let’s look at the output now.
现在让我们看一下输出。
Output
输出量
Token List:
Hello
from
JournalDev!
Indeed, we seem to have got the correct tokens!
确实,我们似乎已经获得了正确的令牌!
Similarly, let’s now look at using strtok_r()
.
同样,让我们现在来看一下使用strtok_r()
。
使用strtok_r()函数 (Using the strtok_r() function)
This function is very similar to the strtok()
function. The key difference is that the _r
means that this is a re-entrant function.
此函数与strtok()
函数非常相似。 关键区别在于_r
表示这是可重入函数。
A reentrant function is a function that can be interrupted during its execution. This type of function can also be safely called again, to resume execution!
可重入函数是可以在其执行期间中断的函数。 也可以再次安全地调用此类函数,以恢复执行!
This is why it is a “re-entrant” function. Just because it can safely enter again!
这就是为什么它是“可重入”功能的原因。 只是因为它可以安全地再次进入!
Due to this fact, re-entrant functions are thread-safe, meaning that they can safely be interrupted by threads, just because they can resume again without any harm.
因此,重入函数是线程安全的,这意味着它们可以安全地被线程中断,因为它们可以再次恢复而不会造成任何伤害。
Now, similar to strtok()
, the strtok_r()
function is a thread-safe version of it.
现在,类似于strtok()
, strtok_r()
函数是该线程的线程安全版本。
However, this has an extra parameter to it, called the context. We need this, so that the function can resume from the right place.
但是,这有一个额外的参数,称为context 。 我们需要这样做,以便函数可以从正确的位置恢复。
NOTE: If you’re using Windows, the equivalent function is strtok_s(). strtok_r() is for Linux / Mac based systems!
注意 :如果使用的是Windows,则等效功能为strtok_s() 。 strtok_r()适用于基于Linux / Mac的系统!
#include <string.h>
char *strtok_r(char *str, const char *delim, char **context);
The context
parameter is a pointer to the character, which strtok_r
uses internally to save its state.
context
参数是指向字符的指针, strtok_r
内部使用该指针保存其状态。
Usually, we can just pass it from a user-declared pointer.
通常,我们可以从用户声明的指针传递它。
Let’s look at the same example for strtok()
, now using strtok_r()
(or strtok_s()
on Windows).
让我们看一下strtok()
的相同示例,现在使用strtok_r()
(或Windows上的strtok_s()
)。
#include <stdio.h>
#include <string.h>
int main() {
// Our input string
char input_string[] = "Hello from JournalDev!";
// 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;
}
Output
输出量
Token List:
Hello
from
JournalDev!
While we get the same output, this version is better, since it is thread safe!
虽然我们得到相同的输出,但是此版本更好,因为它是线程安全的!
结论 (Conclusion)
In this article, we learned about how we could use the strtok() and strtok_r() functions in C, to tokenize strings easily.
在本文中,我们学习了如何在C中使用strtok()和strtok_r()函数轻松地对字符串进行标记。
For similar content, do go through our tutorial section on C programming!
对于类似的内容,请阅读我们有关C编程的教程部分!
参考资料 (References)
- Linux manual page on strtok() and strtok_r() functions in C 有关C语言中strtok()和strtok_r()函数的Linux手册页
翻译自: https://www.journaldev.com/42293/strtok-strtok-r-functions-c
c语言中strtok函数