#include <stdio.h>
#include <string.h>
int main() {
char *slogan = "together{kaliya} [namak]";
char *slow_gun = strdup(slogan);
char *token = strsep(&slow_gun, "{");
printf ("\n slow_gun: %s\n token: %s\n", slow_gun, token);
return 0;
}
当我执行它时:
$ cc -o try try_strsep.c
$ ./try
slow_gun: kaliya} [namak]
token: together
但是,当我将char *口号改为:
char *slogan = "kalia} [namak]";
并执行相同的程序:
$ vi try_strsep.c
$ cc -o try try_strsep.c
$ ./try
slow_gun: (null)
token: kalia} [namak]
我的问题是,所以当我使用strsep()并且输入字符串没有我正在寻找的模式时,strsep()的返回错误。我可以验证strsep()是否找不到模式的唯一方法是检查if (slow_gun == NUll)
。
如果我有char *slogan = "together{"
,则strsep
会成功返回token
,但会将slow_gun
返回空白(不是null
)
$ cc -o try try_strsep.c
$ ./try
slow_gun:
token: together
有没有办法可以避免这种IF检查并依赖函数返回我的substr,如果不存在,返回NULL
?
答案 0 :(得分:12)
不,没有办法避免支票slow_gun == NULL
。 strsep
行为Here's a description:
char *strsep(char **stringp, const char *delim);
说明
如果*stringp
为NULL
,则strsep()
函数会返回NULL
,并且不执行任何操作。否则,此函数在字符串*stringp
中查找第一个标记,其中标记由字符串delim
中的符号分隔。通过使用空字节('\0'
)覆盖分隔符来终止此令牌,并更新*stringp
以指向令牌。如果未找到分隔符,则将令牌视为整个字符串*stringp
,并将*stringp
设为NULL
。返回值
strsep()
函数返回指向令牌的指针,即返回原始值*stringp
。
因此,如果未找到匹配项,则strsep
返回指向原始字符串的指针,并将slow_gun
输入设置为NULL。
如果分隔符是字符串中的最后一个字符,则该字符被'\ 0'覆盖,slow_gun
被设置为以下字符,恰好是终止原始字符串的'\ 0'。这就是print语句打印空字符串的原因。
注意您错误地使用strdup
,调用者负责在该函数返回的指针上调用free
。
答案 1 :(得分:7)
返回strsep()是错误的
那不对。 strsep()
返回它找到的第一个标记 - 字符串的开头按定义是第一个标记。只是在这种情况下没有找到终止令牌的分隔符(所以字符串的其余部分是令牌)。
strsep()
并非用于“查找模式” - 它用于根据一组分隔符分隔标记。如果要查找字符,请使用strchr()
或strpbrk()
。
答案 2 :(得分:2)
strsep表现正确 - 来自man page:
strsep()
函数位于*stringp
引用的字符串中, 字符串delim中的任何字符的第一次出现(或者 终止\0
字符)并用\0
替换它。的位置 分隔符后面的下一个字符(或NULL
,如果结束 到达的字符串)存储在*stringp
中。原始价值 <{1}}已退回。
第二种情况 正确 - 由于未找到分隔符,因此第一个参数设置为指向*stringp
并返回原始字符串。如您所说,您需要检查NULL
以检测此情况。
(顺便说一句,这是一个令人困惑的变量名称选择)。