Подсчет количества раз, когда символ встречается в строке в C

Я новичок в C, и я работаю над собственной функцией explode . Я пытаюсь подсчитать, сколько раз указанный символ возникает в строке.

 int count_chars(char * string, char * chr) { int count = 0; int i; for (i = 0; i < sizeof(string); i++) { if (string[i] == chr) { count++; } } return count; } 

Он просто возвращает 0 каждый раз. Может кто-нибудь объяснить, почему, пожалуйста? 🙂

Ваш код безнадежно испорчен. Вот как это должно выглядеть:

 int count_chars(const char* string, char ch) { int count = 0; int i; // We are computing the length once at this point // because it is a relatively lengthy operation, // and we don't want to have to compute it anew // every time the i < length condition is checked. int length = strlen(string); for (i = 0; i < length; i++) { if (string[i] == ch) { count++; } } return count; } 

См. Этот запуск кода на примере ввода .

Вот что вы делаете неправильно:

  1. Поскольку вы хотите найти символ , вторым параметром должен быть символ (а не char* ). Это имеет последствия позже (см. № 3).
  2. sizeof(string) не дает вам длину строки. Он дает размер (в байтах) указателя в вашей архитектуре, который является постоянным числом (например, 4 на 32-битных системах).
  3. Вы сравниваете какое-то значение, которое не является адресом памяти для адреса памяти, на который указывает chr . Это сравнение яблок и апельсинов и всегда будет возвращать false , поэтому if никогда не удастся.
  4. Вместо этого вы сравните символ ( string[i] ) со вторым параметром функции (именно по этой причине этот char также является char ).

«Лучшая» версия вышеупомянутого

В комментариях ниже правильно указаны части исходного ответа, которые не являются обычным способом делать вещи на C, могут привести к медленному коду и, возможно, к ошибкам в (по общему признанию, необычным) обстоятельствам.

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

 int count_chars(const char* string, char ch) { int count = 0; for(; *string; count += (*string++ == ch)) ; return count; } 

Примечание. Я намеренно написал цикл таким образом, чтобы подчеркнуть, что на каком-то этапе вам нужно провести линию между тем, что возможно и что предпочтительнее.

См. Этот запуск кода на примере ввода .

Вероятно, вы хотите использовать функцию, которая фактически получает длину string , а не sizeof .

sizeof получит размер типа данных . Он не вернет длину строки. strlen вернет длину строки.

Это C! Он разработан, чтобы быть кратким!

 int count_chars(const char* string, char ch) { int c = 0; while (*string) c += *(string++) == ch; return c; } 

Обновить

Я попытаюсь объяснить, как это работает:

 int c = 0; 

Это будет счет количества найденных совпадений.

 while (*string) 

Это оператор управления циклом и будет продолжать итерацию цикла до тех пор, пока условие истинно. В этом случае условие равно *string . В C строки хранятся «null terminated», что означает, что последний символ строки является символом со значением 0 (‘\ 0’). *string оценивает символ, на который указывает указатель. Выражения в C являются «истинными», если они оценивают любое ненулевое значение и «ложь», если они оценивают до нуля. *string – это выражение, поэтому любая ненулевая символьная *string указывает на true, а «\ 0» в конце строки – false. Таким образом, это прекратится, если *string указывает на конец строки.

 *(string++) 

Это выражение, которое оценивает значение, на которое указывает указатель. ++ – это пост-инкремент, поэтому значение указателя перемещается на одно место вперед, то есть указывает на следующий символ в строке. Обратите внимание, что значение выражения не совпадает с значением *string после того, как выражение было оценено, потому что указатель перемещен.

 *(string++) == ch 

Это выражение сравнения, оно сравнивает значение *string (до его обновления) со значением ch . В C результат этого является целым числом (в C нет типа bool), который имеет значение «1», если выражение истинно и «0», если выражение является ложным.

 c += *(string++) == ch; 

Мы знаем бит после того, как символ += ‘1’, если символ – тот, который мы ищем, и ‘0’, если нет. Значение += сокращается для:

 c = c + (*(string++) == ch); 

поэтому он будет увеличивать счетчик, если найден соответствующий символ.

В этом конкретном случае преимущество в синтаксисе += мало, но если c был более сложным, скажите *(variable [index].structure_member [index2]) тогда он будет оцениваться только один раз.

; в конце знаменует конец инструкции и потому что нет { после while , это также отмечает конец цикла while.

Когда все сказали вам ответ,

1) вы не можете использовать размер, но вместо этого strlen (string). Они сказали вам причину

2) Я думаю, что все пропустили его здесь, второй параметр, который вы использовали, – char pointer.but, все сказали вам сделать это как chr, но если вы хотите сделать это все еще.

то в цикле он должен быть

 if ( string(i)== *chr ) \\ not just ch remember you declared it as a pointer ch gives the address but you want the character so use *ch 

Вы также можете использовать функцию strchr.

  int count_chars (char *string, char ch) { int i; if(string=strchr(string,'s'))++i; while (string!=NULL) if(string=strchr(string+1,chr) ++i; return i; }