Подсчет количества раз, когда символ встречается в строке в C - PullRequest
5 голосов
/ 08 сентября 2011

Я новичок в 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 ]

12 голосов
/ 08 сентября 2011

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

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).

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

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

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

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

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

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

2 голосов
/ 08 сентября 2011

Это С! Он создан для краткости!

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 строки хранятся с нулевым окончанием, что означает, что последний символ строки - это символ со значением 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.

2 голосов
/ 08 сентября 2011

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

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

0 голосов
/ 08 сентября 2011

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

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

2) Я думаю, что все здесь пропустиливторой параметр, который вы использовали, это char pointer. но все говорили, что вы должны сделать его как chr, но если вы хотите сделать это все еще.Вы также можете использовать функцию 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;
        }
...