有没有一种方法在C语言中计算标记数?

13

我正在使用strtok将字符串分割成标记。有没有人知道实际计算标记数量的函数?

我有一个命令字符串,需要将其拆分并将参数传递给execve()

谢谢!

编辑

execve将参数作为char**,因此我需要分配一个指针数组。 我不知道要分配多少个指针,除非知道有多少个标记。


9
strtok() 和增加计数器? - alex
1
realloc 应该解决不提前知道大小的问题。 - Kerrek SB
3个回答

11

一种方法是使用带有计数器的strtok。但是,这会修改原始字符串。

另一种方法是在循环中使用strchr,如下所示:

int count = 0;
char *ptr = s;
while((ptr = strchr(ptr, ' ')) != NULL) {
    count++;
    ptr++;
}

如果您有多个分隔符,请使用strpbrk:
while((ptr = strpbrk(ptr, " \t")) != NULL) ...

当有多个字段分隔符(例如标点符号)时,strchr() 变得很麻烦。 - jim mcnamara
在那种情况下,你可以使用 strpbrk - nneonneo
1
好的,我已经修改了我的答案,包括 strpbrk。感谢您的反馈。 - nneonneo
抱歉这样冒昧地打扰,但这似乎是我找到的最好的答案。是否有一种方法可以获取定界符之间每个段落的长度。再次感谢这个答案。祝好 @nneonneo - Isabel Inc
你可以跟踪ptr的先前值,并取两者之间的差异 - 指针指向同一字符串的不同部分。 - nneonneo

4

由于令牌数实际上只是使用定界符的出现频率加1,因此您的问题归结为查找字符串中字符出现的次数。

假设在C语言的strtok函数中使用的定界符是' '

int count =0,i;
char str[20] = "some string here";

for(i=0;i<strlen(str);i++){
    if(str[i] == ' ')
        count++;
}

令牌数量将与计数器数量相同,加1。

如果允许使用多个分隔符,这种方法虽然可行,但会变得繁琐。 - Carey Gregory
我想我们可以使用相同的程序,并应该注意边角情况。 - router
这将把两个连续的空格视为两个不同的单词分隔符。strtok() 不会将连续的分隔符视为单个分隔符吗? - jvriesem

1

以下是基于strtok的版本,它不会修改原始字符串,而是使用临时副本。该版本适用于任何将制表符和空格字符用作分隔符的组合。该函数为:

unsigned long int getNofTokens(const char* string){
  char* stringCopy;
  unsigned long int stringLength;
  unsigned long int count = 0;

  stringLength = (unsigned)strlen(string);
  stringCopy = malloc((stringLength+1)*sizeof(char));
  strcpy(stringCopy,string);

  if( strtok(stringCopy, " \t") != NULL){
    count++;
    while( strtok(NULL," \t") != NULL )
        count++;
  }

  free(stringCopy);
  return count;
}

一个函数调用可以是:

char stringExample[]=" wordA 25.4 \t 5.6e-3\t\twordB 4.5e005\t ";
printf("number of elements in stringExample is %lu",getNofTokens(stringExample));

输出为

number of elements in stringExample is 5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接