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 существует. Вот почему у вас есть бесконечный цикл.
Возможно, вы захотите сделать некоторую арифметику указателей, чтобы решить вашу проблему здесь;)