Подсчет количества раз, когда символ встречается в строке в 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 каждый раз. Кто-нибудь может объяснить почему, пожалуйста? :)
4 ответа:
Ваш код безнадежно испорчен. Вот как это должно выглядеть:
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; }
Смотрите этот код, выполняемый на примере ввода.
Вот что вы делаете неправильно:
Поскольку вы хотите найти символ , второй параметр должен быть символом (а не
char*
), это имеет значение позже (см. #3).sizeof(string)
не дает вам длину строки. Он дает размер (в байтах) указателя в вашей архитектуре, который является постоянным числом (например, 4 в 32-разрядных системах).- Вы сравниваете некоторое значение, которое является не адресом памяти, с адресом памяти, на который указывает
chr
. Это сравнение яблок и апельсинов, и всегда будет возвращатьfalse
, поэтомуif
никогда не будет успешным.- вместо этого вы хотите сравнить символ (
string[i]
) ко второму параметру функции (именно поэтому он также являетсяchar
).A " лучше" версия выше
Комментаторы ниже правильно определили части исходного ответа, которые не являются обычным способом делать вещи в 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
will получить размер типа данных . Он будет не возвращать длину строки.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])
, то он был бы оценен только один раз.The
;
в конце отмечает конец оператора, и поскольку послеwhile
Нет{
, он также отмечает конец циклаwhile
.
Как все вам ответили,
1) Вы не можете использовать размер but вместо strlen (string).Они сказали вам причину
2) я думаю, что все пропустили его здесь, второй параметр, который вы использовали, - это указатель char.но все говорили вам, чтобы сделать это как 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; }