Подсчет количества раз, когда символ встречается в строке в 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 5

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).
  1. sizeof(string) не дает вам длину строки. Он дает размер (в байтах) указателя в вашей архитектуре, который является постоянным числом (например, 4 в 32-разрядных системах).
  2. Вы сравниваете некоторое значение, которое является не адресом памяти, с адресом памяти, на который указывает chr. Это сравнение яблок и апельсинов, и всегда будет возвращать false, поэтому if никогда не будет успешным.
  3. вместо этого вы хотите сравнить символ (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;
        }