C - использование strchr для подсчета вхождений символа в строку

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

Это задание, поэтому я не ищу никого, кто бы сделал за меня домашнее задание, а просто указал, где я неправ и почему, чтобы я мог понять, как это исправить. Буду признателен за любую помощь, которую вы готовы оказать.

Вот код, который я написал:

#include <stdio.h>
#include <string.h>

int charCounter(char* pString, char c);

int main(void)
{
    char* inpString = "Thequickbrownfoxjumpedoverthelazydog.";
    int charToCount;
    int eCount;

    eCount = 0;
    charToCount = 'e';
    eCount = charCounter(inpString, charToCount);
    printf("\nThe letter %c was found %d times.", charToCount, eCount);

    return 0;
} // end main

int charCounter(char* pString, char c)
{
    int count = 0;
    char* pTemp;

    do
    {
        pTemp = strchr(pString, c);
        count++;
    }
    while(pTemp != NULL);

    return count;
} // end countCharacter

4 ответа

Решение

Ваш цикл всегда смотрит с начала pStringи всегда находит первое "е" снова и снова.

Если вы объявите char* pTemp = pString; тогда вы можете выполнить итерацию немного по-другому (я вставил неправильную версию ранее, извините!):

char* pTemp = pString;

while(pTemp != NULL)                                                                                                    
{                                                                                                                       
    pTemp = strchr(pTemp, c);                                                                                                           
    if( pTemp ) {
        pTemp++;
        count++;
    }                                                                                                
}

Это силы pTemp чтобы указать сразу после персонажа, которого вы только что нашли, прежде чем искать следующий.

Было бы проще просто сделать:

char* pTemp = pString;
while( *pTemp )
    if( *pTemp++ == c) count++;

Хорошо, подумав об этом, даже после того, как у вас уже есть эта работа, я изменил внутренний цикл на форму, которой я более доволен:

while( (pTemp = strchr(pTemp, c)) != NULL) {                                                                                                                       
   count++;                                                                                                             
   pTemp++;
}

Вы всегда перезапускаете с самого начала. Не удивительно, что ты никогда не кончишь.

char* pTemp; // Init here = pString
do {
    pTemp = strchr(pString, c); // pString? Really? Should be pTemp
    count++;
} while(pTemp != NULL); // pTemp != NULL is verbose for pTemp here

Тем не менее, лучше избегать библиотечной функции и делать прямой цикл по всем элементам.

Просто чтобы запрыгнуть в вагон

size_t count(const char* s, char c) {
    size_t r = 0;
    for(; *s; s++)
        r += *s == c;
    return r;
}

strchr() всегда смотрит в одно и то же место, он не будет проходить через строку...

Попробуйте эту модификацию, чтобы пройти через строку, используя длину строки, и простой char Сравнение:

int i, len = strlen(pString);
count = 0;
for(i=0;i<len;i++)
{
    if(pString[i] == c) count++; //increment count only if c found
}

return count;  

Без использования strlen() (обратиться к комментарию)

i=-1, count = 0;
while(pString[++i])
{
   if(pString[i] == c) count++;
}  
return count;

strchr возвращает указатель на первое вхождение символа c в pString.

Таким образом, если вы дадите указатель на начало вашей строки в каждом цикле, pTemp всегда будет иметь одинаковое значение и никогда не будет NULL, если символ c существует. Вот почему у вас есть бесконечный цикл.

Возможно, вы захотите сделать некоторую арифметику указателей, чтобы решить вашу проблему здесь;)

Другие вопросы по тегам