strtok和strep在C中有什么区别
有人能给我解释一下strtok()和strep()之间有什么区别吗? 它们的优点和缺点是什么?strtok和strep在C中有什么区别,c,strtok,strsep,C,Strtok,Strsep,有人能给我解释一下strtok()和strep()之间有什么区别吗? 它们的优点和缺点是什么? 为什么我要选择一个而不是另一个。摘自GNU C库手册-: strep和strtok_r之间的一个区别是,如果输入字符串在一行中包含来自分隔符的多个字符,则strep将为来自分隔符的每对字符返回一个空字符串。这意味着程序在处理空字符串之前,通常应该测试是否返回空字符串 和之间的一个主要区别是,strtok()是标准化的(由C标准,因此也是由POSIX),但不是标准化的(由C或POSIX;它在GNU C库
为什么我要选择一个而不是另一个。摘自GNU C库手册-:
strep
和strtok_r
之间的一个区别是,如果输入字符串在一行中包含来自分隔符的多个字符,则strep
将为来自分隔符的每对字符返回一个空字符串。这意味着程序在处理空字符串之前,通常应该测试是否返回空字符串
和之间的一个主要区别是,
strtok()
是标准化的(由C标准,因此也是由POSIX),但不是标准化的(由C或POSIX;它在GNU C库中可用,并且源于BSD)。因此,可移植代码更可能使用strtok()
而不是strep()
另一个区别是,对不同字符串上的strep()
函数的调用可以交错,而使用strtok()
(尽管可以使用strtok_r()
)来实现这一点)。因此,在库中使用strep()
不会意外中断其他代码,而在库函数中使用strtok()
必须记录在案,因为同时使用strtok()
的其他代码无法调用库函数
strep()
at的手册页上写着:
strsep()函数是作为strtok(3)的替代品引入的,因为后者不能处理空字段
因此,另一个主要区别是他在回答中强调的区别strtok()
允许在单个令牌之间使用多个分隔符,而strep()
要求令牌之间使用单个分隔符,并将相邻分隔符解释为空令牌
strep()
和strtok()
都可以修改它们的输入字符串,并且都不允许您识别标记令牌结尾的分隔符字符(因为两者都在令牌结尾后的分隔符上写入NUL'\0'
)
什么时候使用它们?
- 如果您想要空令牌,而不是在令牌之间允许多个分隔符,并且不介意可移植性,则可以使用
strep()
- 如果希望在令牌之间允许多个分隔符,而不希望使用空令牌(并且POSIX对您来说是足够可移植的),则可以使用
strtok_r()
- 只有当有人威胁你的生命时,如果你不这样做,你才会使用strtok()。而你只会使用它足够长的时间,让你摆脱生命威胁的情况;然后,您将再次放弃对它的所有使用。它有毒;不要使用它。编写自己的
或strtok\u r()
比使用strep()
更好strtok()
strtok()
函数,则该函数是有毒的。如果库函数使用strtok(),则必须清楚地记录它
那是因为:
strtok()
并调用同样使用strtok()
的函数,则会中断调用函数strtok()
的函数,则会中断函数对strtok()
的使用strtok()
在停止时继续。除了“请勿使用strtok()
”之外,没有其他明智的方法来解决此问题
- 如果可用,可以使用
strep()
- 如果POSIX可用,您可以使用它
- 如果有微软的,你可以使用它
- 名义上,您可以使用ISO/IEC 9899:2011附录K.3.7.3.1函数
strtok__()
strep()
:
POSIXstrtok_r()
:
Microsoftstrtok\u s()
:
附件Kstrtok_s()
:
请注意,这有4个参数,而不是像
strtok()
上的其他两个变量那样有3个。strtok()
和strep()
的第一个区别是它们处理输入字符串中连续分隔符字符的方式
strtok()
处理的连续分隔符字符:
在输出中,您可以依次看到令牌“bbb”
和“ccc”
strtok()
不指示连续分隔符的出现。另外,strtok()
修改输入字符串
strep()处理的连续分隔符字符
:
输出:
# ./example1_strtok
Original String: aaa-bbb --ccc-ddd
aaa
bbb
ccc
ddd
Original String: aaa
# ./example1_strsep
Original String: aaa-bbb --ccc-ddd
aaa
bbb
<empty> <==============
<empty> <==============
ccc
ddd
ptr1 is NULL
Original String: aaa
# ./example2_strtok
Original String: aaa --bbb-ccc
aaa
Original String: ttt -vvvv
ttt
vvvv
another_function_callng_strtok: I am done.
# ./example2_strsep
Original String: aaa --bbb-ccc
aaa
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
<empty>
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
<empty>
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
bbb
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
ccc
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
函数function\u callng\u strtok()
只打印令牌“aaa”
,不打印输入字符串的其余令牌,因为它调用了另一个函数\u callng\u strtok()
,后者反过来调用strtok()
,并设置strtok()的静态指针
到NULL
提取完所有令牌后。控件返回到函数调用
而循环时,strtok()
由于指向NULL
的静态指针而返回NULL
,从而使循环条件false
并退出循环
当另一个strep()
未完成时调用strep()
:
#include <stdio.h>
#include <string.h>
void another_function_callng_strtok(void)
{
char str[] ="ttt -vvvv";
char* delims = " -";
char* token;
printf ("Original String: %s\n", str);
token = strtok (str, delims);
while (token != NULL) {
printf ("%s\n", token);
token = strtok (NULL, delims);
}
printf ("another_function_callng_strtok: I am done.\n");
}
void function_callng_strtok ()
{
char str[] ="aaa --bbb-ccc";
char* delims = " -";
char* token;
printf ("Original String: %s\n", str);
token = strtok (str, delims);
while (token != NULL)
{
printf ("%s\n",token);
another_function_callng_strtok();
token = strtok (NULL, delims);
}
}
int main(void) {
function_callng_strtok();
return 0;
}
#include <stdio.h>
#include <string.h>
void another_function_callng_strsep(void)
{
char str[] ="ttt -vvvv";
const char* delims = " -";
char* token;
char* ptr = str;
printf ("Original String: %s\n", str);
while ((token = strsep(&ptr, delims)) != NULL) {
if (*token == '\0') {
token = "<empty>";
}
printf("%s\n", token);
}
printf ("another_function_callng_strsep: I am done.\n");
}
void function_callng_strsep ()
{
char str[] ="aaa --bbb-ccc";
const char* delims = " -";
char* token;
char* ptr = str;
printf ("Original String: %s\n", str);
while ((token = strsep(&ptr, delims)) != NULL) {
if (*token == '\0') {
token = "<empty>";
}
printf("%s\n", token);
another_function_callng_strsep();
}
}
int main(void) {
function_callng_strsep();
return 0;
}
#包括
#包括
void另一个函数调用strep(void)
{
字符str[]=“ttt-VVV”;
骗局
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
const char* teststr = "aaa-bbb --ccc-ddd"; //Contiguous delimiters between bbb and ccc sub-string
const char* delims = " -"; // delimiters - space and hyphen character
char* token;
char* ptr1;
char* ptr = strdup(teststr);
if (ptr == NULL) {
fprintf(stderr, "strdup failed");
exit(EXIT_FAILURE);
}
ptr1 = ptr;
printf ("Original String: %s\n", ptr);
while ((token = strsep(&ptr1, delims)) != NULL) {
if (*token == '\0') {
token = "<empty>";
}
printf("%s\n", token);
}
if (ptr1 == NULL) // This is just to show that the strsep() modifies the pointer passed to it
printf ("ptr1 is NULL\n");
printf ("Original String: %s\n", ptr);
free (ptr);
return 0;
}
# ./example1_strsep
Original String: aaa-bbb --ccc-ddd
aaa
bbb
<empty> <==============
<empty> <==============
ccc
ddd
ptr1 is NULL
Original String: aaa
#include <stdio.h>
#include <string.h>
void another_function_callng_strtok(void)
{
char str[] ="ttt -vvvv";
char* delims = " -";
char* token;
printf ("Original String: %s\n", str);
token = strtok (str, delims);
while (token != NULL) {
printf ("%s\n", token);
token = strtok (NULL, delims);
}
printf ("another_function_callng_strtok: I am done.\n");
}
void function_callng_strtok ()
{
char str[] ="aaa --bbb-ccc";
char* delims = " -";
char* token;
printf ("Original String: %s\n", str);
token = strtok (str, delims);
while (token != NULL)
{
printf ("%s\n",token);
another_function_callng_strtok();
token = strtok (NULL, delims);
}
}
int main(void) {
function_callng_strtok();
return 0;
}
# ./example2_strtok
Original String: aaa --bbb-ccc
aaa
Original String: ttt -vvvv
ttt
vvvv
another_function_callng_strtok: I am done.
#include <stdio.h>
#include <string.h>
void another_function_callng_strsep(void)
{
char str[] ="ttt -vvvv";
const char* delims = " -";
char* token;
char* ptr = str;
printf ("Original String: %s\n", str);
while ((token = strsep(&ptr, delims)) != NULL) {
if (*token == '\0') {
token = "<empty>";
}
printf("%s\n", token);
}
printf ("another_function_callng_strsep: I am done.\n");
}
void function_callng_strsep ()
{
char str[] ="aaa --bbb-ccc";
const char* delims = " -";
char* token;
char* ptr = str;
printf ("Original String: %s\n", str);
while ((token = strsep(&ptr, delims)) != NULL) {
if (*token == '\0') {
token = "<empty>";
}
printf("%s\n", token);
another_function_callng_strsep();
}
}
int main(void) {
function_callng_strsep();
return 0;
}
# ./example2_strsep
Original String: aaa --bbb-ccc
aaa
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
<empty>
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
<empty>
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
bbb
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
ccc
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.