6
#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 *slogan 更改为:

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

4

3 回答 3

13

不,没有办法避免检查slow_gun == NULL下面是strsep's 行为的描述:

char *strsep(char **stringp, const char *delim);

描述
如果*stringpNULL,该strsep()函数返回NULL并且不执行任何其他操作。否则,此函数查找字符串中的第一个标记*stringp,其中标记由字符串中的符号分隔delim'\0'该标记通过用空字节 ( )覆盖分隔符来终止,并*stringp更新为指向该标记。如果没有找到分隔符,则将标记视为整个 string *stringp,并*stringp制作NULL

返回值
strsep()函数返回一个指向令牌的指针,即返回 的原始值*stringp

因此,如果未找到匹配项,则strsep返回指向原始字符串的指针并将slow_gun输入设置为 NULL。

如果定界符是字符串中的最后一个字符,则该字符将被 '\0' 覆盖并slow_gun设置为下一个字符,该字符恰好是终止原始字符串的 '\0'。这就是 print 语句打印空字符串的原因。

注意您使用strdup不正确,调用者负责调用free该函数返回的指针。

于 2011-07-28T21:43:44.847 回答
7

strsep() 的返回错误

那是不对的。 strsep()返回它找到的第一个标记 - 根据定义,字符串的开头是第一个标记。只是在这种情况下没有找到分隔符来终止令牌(因此字符串的其余部分是令牌)。

strsep()不打算用于“查找模式” - 它用于根据一组分隔符分隔标记。如果要查找字符,请使用strchr()strpbrk()

于 2011-07-28T21:41:12.403 回答
2

strsep 行为正确-来自手册页

strsep()函数在由 引用的字符串中定位*stringp字符串 delim(或终止\0字符)中任何字符的第一次出现,并将其替换为\0。分隔符之后的下一个字符的位置(或者NULL,如果到达字符串的末尾)存储在*stringp. 的原始值 *stringp被返回。

第二种情况正确的——因为没有找到分隔符,所以第一个参数设置为指向NULL并返回原始字符串。正如您所说,您需要检查if (slow_gun == NUll)以检测到这一点。

(顺便说一句,这是一个非常令人困惑的变量名选择)。

于 2011-07-28T21:41:28.403 回答