unbuffer
在解析时将空字符放入输入字符串的不同位置。仅在strtok_r
返回strtok_r
后才会恢复原始字符串。
如果我需要在长字符串的开头附近提取令牌怎么办?如果我离开循环,输入字符串将保持断开状态。我可以尝试手动恢复分隔符,但我不知道它是否是最后一个令牌。
问题是没有记录NULL
值。
saveptr
答案 0 :(得分:2)
strtok()和strtok_r()是可怕的功能:
最好是完全避免使用strtok()和strtok_r(),并使用strspn()和strcspn()。以下功能就是这样。返回值类似于snprintf()的值:找到的令牌中的字符数(不计算终止的NUL字节)
#include <stdio.h>
#include <string.h>
size_t extract_nth_token_ohne_strtok_r(char *res, size_t maxlen, const char *str, const char *delim, int n)
{
size_t pos, len;
int itok;
for (itok=0,pos=0; str[pos]; ) {
len = strcspn(str+pos, delim);
if (itok++ == n) {
if (len < maxlen) memcpy(res, str+pos, len), res[len] = 0;
else res[0] = 0;
return len;
}
pos += len;
if (str[pos]) pos++;
}
res[0] = 0;
return 0;
}
int main(void)
{
char * omg = "zero one\ttwo \tfour\nfive" ;
char token[80];
size_t toklen;
int ii;
printf("\n## With a large enough buffer:\n" );
for (ii=0; ii < 7; ii++) {
toklen = extract_nth_token_ohne_strtok_r(token, sizeof token
, omg, " \t\n", ii);
printf("%d: res=%zu \"%s\"\n" , ii, toklen, token );
}
printf("\n## With 4-character buffer:\n" );
for (ii=0; ii < 7; ii++) {
toklen = extract_nth_token_ohne_strtok_r(token, 4
, omg, " \t\n", ii);
printf("%d: res=%zu \"%s\"\n" , ii, toklen, token );
}
return 0;
}
注意:如果你做想要将连续的whitspace视为一个,你可以将if (str[pos]) pos++;
替换为:
pos += strspn(str+pos, delim);