其手册页中strsep()
的说明指出,在到达第一个分隔符时,
通过使用空字节(
'\0'
)覆盖分隔符来终止此标记,并更新*stringp
以指向令牌。
其中*stringp
是输入字符串。
我想知道是否有任何函数只会更新*stringp
以指向令牌而不用'\0'
替换分隔符。我有3个可能的分隔符,我可以将其作为strsep()
输入到" \t\n"
,因此像strchr()
这样只搜索单个分隔符的内容不会有效(不是有效的,在最小)。由于我需要稍后打印完整的字符串,否则我必须执行memcpy()
才能在以后打印字符串。
(另外,任何人都可以解释为什么以这种方式实施......?)
答案 0 :(得分:2)
这是一个实现:
token = non_nulling_strsep(char** stringp, const char* delims);
与strsep
非常相似,只是它将*stringp
设置为实际终止令牌的分隔符,而不是后续字符。与strsep
不同,这意味着您可以将*stringp - token
视为令牌的长度,这很有用,因为令牌不是以空值终止的,因为它与strsep
一样。如果字符串中没有其他标记,*stringp - token
将为0,因此您应该测试结束标记扫描循环的条件。
char* non_nulling_strsep (char** stringp, const char* delims) {
char* token = *stringp + strspn(*stringp, delims);
*stringp = token + strcspn(token, delims);
return token;
}
您可以像这样扫描令牌:
{
char *end = buffer;
for (char *token = non_nulling_strsep(&end, " \t\n");
end - token;
token = non_nulling_strsep(&end, " \t\n")) {
printf("Found '%.*s'\n", end - token, token);
}
}
这是另一个可能的界面,可能会更好。这个返回长度(如果没有更多的标记,则返回0)并将字符串指针设置为下一个标记的开头(如果没有更多标记,则将字符串结束)。
size_t next_token(char** tokenp, const char* delims) {
*tokenp += strspn(*tokenp, delims);
return strcspn(*tokenp, delims);
}
有了这个,你就像这样循环:
{
char *token = buffer;
for (size_t token_len;
(token_len = next_token(&token, " \t\n"));
token += token_len) {
printf("Found '%.*s'\n", token_len, token);
}
}