计算字符在C中的字符串中出现的次数

时间:2011-09-08 13:45:24

标签: c arrays string explode

我是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 个答案:

答案 0 :(得分:12)

你的代码无可救药地存在缺陷。这是应该的样子:

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;
}

<强> See this code run on example input

这是你做错了什么:

  1. 由于你想找到一个字符,第二个参数应该是一个字符(而不是char*),这稍后会有影响(见#3)。
  2. sizeof(string)没有给出字符串的长度。它给出了体系结构中指针的大小(以字节为单位),它是一个常数(例如32位系统上的4)。
  3. 您正在将内存地址的某个值与内存地址chr进行比较。这是比较苹果和橙子,并将始终返回false,因此if永远不会成功。
  4. 你要做的是将一个字符string[i])与函数的第二个参数进行比较(这就是为什么那个也是char的原因)。
  5. 上述

    的“更好”版本

    下面的评论者已正确识别原始答案的部分内容,这些部分不是在C中执行操作的常用方式,可能会导致代码速度变慢,并且可能导致(在非常特殊情况下)情况下的错误。

    由于我认为count_chars的“正确”实现对于正在使用C语言的第一步的人来说可能过于复杂,我只需将其附加到此处并保留初始答案几乎完整。

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

    注意:我故意以这种方式编写循环,以表明在某个阶段你必须在可能的和可取的之间划清界线。

    <强> See this code run on example input

答案 1 :(得分:2)

您可能希望使用实际长度为string的函数,而不是sizeof

sizeofget the size of the datatype。它将返回字符串的长度。 strlen将返回字符串的长度。

答案 2 :(得分:2)

这是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中,字符串存储为“空终止”,这意味着字符串的最后一个字符是值为0('\ 0')的字符。 *string计算指针指向的字符。 C中的表达式如果评估为任何非零值则为“true”,如果评估为零则为“false”。 *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循环的结束。< / p>

答案 3 :(得分:0)

每个人都告诉你答案,

1)你不能使用大小而是strlen(字符串)。他们告诉你原因

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;
        }