我正在尝试对字符串进行标记,但我需要确切知道两个标记之间何时没有数据。例如,当标记以下字符串“a,b,c,,,d,e
”时,我需要知道“d
”和“e
”之间的两个空插槽...我无法简单地使用它strtok()
。我的尝试如下所示:
char arr_fields[num_of_fields];
char delim[]=",\n";
char *tok;
tok=strtok(line,delim);//line contains the data
for(i=0;i<num_of_fields;i++,tok=strtok(NULL,delim))
{
if(tok)
sprintf(arr_fields[i], "%s", tok);
else
sprintf(arr_fields[i], "%s", "-");
}
使用上述示例执行上述代码将字符a,b,c,d,e放入arr_fields
的前五个元素中,这是不可取的。我需要每个字符的位置进入数组的特定索引:即如果两个字符之间缺少一个字符,则应按原样记录。
答案 0 :(得分:13)
7.21.5.8 strtok功能
该标准针对strtok
:
[#3]序列中的第一个调用搜索字符串
s1
指出第一个不是的字符 包含在s2
指向的当前分隔符字符串中。 如果没有找到这样的字符,那么就没有令牌s1
指向的字符串和strtok
函数返回 空指针。如果找到这样的角色,那就是 开始第一个令牌。
在上面的引用中,我们可以看到您无法使用strtok
作为特定问题的解决方案,因为它会将delims
中的任何连续字符视为单令牌。
您可以轻松实现自己想要的strtok
版本,请参阅本文末尾的摘要。
strtok_single
使用strpbrk (char const* src, const char* delims)
,它将返回指向 delims 中任何字符的第一个匹配项的指针,该字符在以null结尾的字符串 src中找到
如果找不到匹配的字符,该函数将返回NULL。
<强> strtok_single 强>
char *
strtok_single (char * str, char const * delims)
{
static char * src = NULL;
char * p, * ret = 0;
if (str != NULL)
src = str;
if (src == NULL)
return NULL;
if ((p = strpbrk (src, delims)) != NULL) {
*p = 0;
ret = src;
src = ++p;
} else if (*src) {
ret = src;
src = NULL;
}
return ret;
}
样本使用
char delims[] = ",";
char data [] = "foo,bar,,baz,biz";
char * p = strtok_single (data, delims);
while (p) {
printf ("%s\n", *p ? p : "<empty>");
p = strtok_single (NULL, delims);
}
<强>输出强>
foo
bar
<empty>
baz
biz
答案 1 :(得分:2)
如果这是您想要的,则无法使用strtok()
。从手册页:
解析后的两个或多个连续分隔符的序列 string被认为是一个单独的分隔符。分隔字符在 字符串的开头或结尾将被忽略。换句话说: strtok()返回的标记总是非空字符串。
因此,在您的示例中,它只会从c
跳转到d
。
您将不得不手动解析字符串,或者搜索可以让您的生活更轻松的CSV解析库。
答案 2 :(得分:2)
最近我正在寻找解决同一问题的方法并找到了这个帖子。
您可以使用strsep()
。
从手册:
引入了strsep()函数作为strtok(3)的替代, 因为后者无法处理空场。
答案 3 :(得分:1)
如this answer中所述,您需要自己实现strtok
之类的内容。我更喜欢使用strcspn
(而不是strpbrk
),因为它允许更少的if
语句:
char arr_fields[num_of_fields];
char delim[]=",\n";
char *tok;
int current_token= 0;
int token_length;
for (i = 0; i < num_of_fields; i++, token_length = strcspn(line + current_token,delim))
{
if(token_length)
sprintf(arr_fields[i], "%.*s", token_length, line + current_token);
else
sprintf(arr_fields[i], "%s", "-");
current_token += token_length;
}
答案 4 :(得分:0)
答案 5 :(得分:0)
您可以尝试使用strchr
找出,
符号的位置。将您的字符串标记为您找到的标记(使用memcpy
或strncpy
),然后再次使用strchr。您将能够看到两个或多个逗号是否以这种方式彼此相邻(strchr将返回其减法将等于1的数字)并且您可以编写if
语句来处理该情况。