Есть ли способ подсчитать токены в C?

Я использую strtok для разделения строки на токены. Кто-нибудь знает какую-нибудь функцию, которая фактически подсчитывает количество токенов?

У меня есть командная строка, и мне нужно разделить ее и передать аргументы execve() .

Спасибо!

Изменить

execve принимает аргументы как char**, поэтому мне нужно выделить массив указателей. Я не знаю, сколько выделить, не зная, сколько жетонов есть.


person James    schedule 25.10.2012    source источник
comment
strtok() и увеличить счетчик?   -  person alex    schedule 26.10.2012
comment
И realloc должен решить проблему незнания размера заранее.   -  person Kerrek SB    schedule 26.10.2012


Ответы (3)


Один из подходов — просто использовать strtok со счетчиком. Однако это изменит исходную строку.

Другой подход заключается в использовании strchr в цикле, например:

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

Если у вас несколько разделителей, используйте strpbrk:

while((ptr = strpbrk(ptr, " \t")) != NULL) ...
person nneonneo    schedule 25.10.2012
comment
strchr() становится громоздким, когда есть несколько разделителей полей, например знаки препинания. - person jim mcnamara; 26.10.2012
comment
В этом случае вы можете использовать strpbrk. - person nneonneo; 26.10.2012
comment
Хорошо, я изменил свой ответ, включив в него strpbrk. Спасибо за ваш отзыв. - person nneonneo; 26.10.2012
comment
Извините, что вмешиваюсь, но это кажется лучшим ответом, который я нашел. Есть ли способ получить длину каждого сегмента между разделителем. Еще раз спасибо за этот ответ. Привет @nneonneo - person Isabel Inc; 12.09.2016
comment
Вы можете просто отслеживать предыдущее значение ptr и брать разницу между ними — указатели указывают на разные части одной и той же строки. - person nneonneo; 12.09.2016

Поскольку количество токенов не более чем на единицу больше, чем частота появления используемого разделителя. Итак, ваш вопрос сводится к тому, чтобы найти «нет». количество вхождений символа в строку

скажем, разделитель, используемый в функции strtok в c, равен ' '

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

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

Количество жетонов будет таким же, как count+1

person router    schedule 15.10.2014
comment
Выполняет работу, но становится громоздким, если разрешено более одного разделителя. - person Carey Gregory; 19.09.2015
comment
Я думаю, мы можем использовать ту же процедуру и должны позаботиться о крайних случаях. - person router; 20.09.2015
comment
Это будет считать два пробела подряд как два отдельных разделителя слов. Разве strtok() не рассматривает последовательные разделители как один разделитель? - person jvriesem; 29.04.2020

Вот версия, основанная на 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
person gambarimas87    schedule 30.01.2019