简体   繁体   English

strsep()用法及其替代方法

[英]strsep() usage and its alternative

#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;
}

when I execute it: 当我执行它时:

$ cc -o try try_strsep.c
$ ./try

 slow_gun: kaliya} [namak]
 token: together  

But when, I change the char *slogan to: 但是,当我将char *口号改为:

char *slogan = "kalia} [namak]";

and execute the same program: 并执行相同的程序:

$ vi try_strsep.c 
$ cc -o try try_strsep.c
$ ./try

 slow_gun: (null)
 token: kalia} [namak]

My Question is, so when I use strsep() and input string does not have the pattern I am looking for, the return of strsep() is wrong . 我的问题是,所以当我使用strsep()并且输入字符串没有我正在寻找的模式时,返回strsep()是错误的 The only way I can validate whether strsep() could not find the pattern is to check if (slow_gun == NUll) . 我可以验证strsep()是否找不到模式的唯一方法是检查if (slow_gun == NUll)

If I have char *slogan = "together{" then strsep would successfully return token but returns slow_gun to blank (not null ) 如果我有char *slogan = "together{"那么strsep将成功返回token但返回slow_gun为空(不为null

$ cc -o try try_strsep.c
$ ./try

 slow_gun: 
 token: together

Is there a way I could avoid this IF check and rely on the function to return me the substr and if its not there, return NULL ? 有没有办法我可以避免这个IF检查并依赖函数返回我的substr,如果不存在,返回NULL

No, there's no way to avoid the check slow_gun == NULL . 不,没有办法避免检查slow_gun == NULL Here's a description of strsep 's behavior: 这是strsep行为的描述

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

DESCRIPTION 描述
If *stringp is NULL , the strsep() function returns NULL and does nothing else. 如果*stringpNULL ,则strsep()函数返回NULL并且不执行任何其他操作。 Otherwise, this function finds the first token in the string *stringp , where tokens are delimited by symbols in the string delim . 否则,此函数在字符串*stringp查找第一个标记,其中标记由字符串delim符号分隔。 This token is terminated by overwriting the delimiter with a null byte ( '\\0' ) and *stringp is updated to point past the token. 通过用空字节( '\\0' )覆盖分隔符来终止此标记,并更新*stringp以指向令牌。 In case no delimiter was found, the token is taken to be the entire string *stringp , and *stringp is made NULL . 如果未找到分隔符,则将令牌视为整个字符串*stringp ,并将*stringp NULL

RETURN VALUE 返回值
The strsep() function returns a pointer to the token, that is, it returns the original value of *stringp . strsep()函数返回一个指向令牌的指针,也就是说,它返回*stringp的原始值。

So, if no match is found strsep returns a pointer to the original string and sets the slow_gun input to NULL. 因此,如果未找到匹配项,则strsep返回指向原始字符串的指针,并将slow_gun输入设置为NULL。

If the delimiter is the last character in the string, that character is overwritten by '\\0' and slow_gun is set to the following character, which happens to be the '\\0' terminating the original string. 如果分隔符是字符串中的最后一个字符,则该字符将被'\\ 0'覆盖, slow_gun被设置为以下字符,恰好是终止原始字符串的'\\ 0'。 This is why print statement prints an empty string. 这就是print语句打印空字符串的原因。

NOTE You're using strdup incorrectly, the caller is responsible for calling free on the pointer returned by that function. 注意您使用strdup不正确,调用者负责在该函数返回的指针上调用free

the return of strsep() is wrong strsep()的返回是错误的

That's not right. 那是不对的。 strsep() returns the first token it finds - the beginning of the string is by definition the first token. strsep()返回它找到的第一个标记 - 字符串的开头按定义是第一个标记。 It's just that no delimiter has been found to terminate the token in this case (so the remainder of the string is the token). 只是在这种情况下没有找到终止令牌的分隔符(所以字符串的其余部分是令牌)。

strsep() is not intended to be used to 'find a pattern' - it's used to separate tokens based on a set of delimiters. strsep()不打算用于“查找模式” - 它用于根据一组分隔符分隔标记。 If you want to find a character, use strchr() or strpbrk() . 如果要查找字符,请使用strchr()strpbrk()

strsep is behaving correctly - from the man page : strsep表现正常 - 从手册页

The strsep() function locates, in the string referenced by *stringp , the first occurrence of any character in the string delim (or the terminating \\0 character) and replaces it with a \\0 . strsep()函数在*stringp引用的字符串中找到字符串delim(或终止\\0字符)中任何字符的第一个匹配项,并用\\0替换它。 The location of the next character after the delimiter character (or NULL , if the end of the string was reached) is stored in *stringp . 分隔符后面的下一个字符的位置(如果到达字符串的末尾,则为NULL )存储在*stringp The original value of *stringp is returned. 返回*stringp的原始值。

The second case is correct - since the delimeter isn't found the first parameter is set to point at NULL and the original string is returned. 第二种情况正确的 - 由于未找到分隔符,因此第一个参数设置为指向NULL并返回原始字符串。 As you say, you need to check for if (slow_gun == NUll) to detect this. 如你所说,你需要检查if (slow_gun == NUll)来检测这个。

(incidentally, that's a horribly confusing choice of variable names). (顺便说一句,这是一个令人困惑的变量名称选择)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM