【问题标题】:What is the data type of text[i]?text[i] 的数据类型是什么?
【发布时间】:2021-12-13 23:04:19
【问题描述】:

我正在尝试使用此自定义函数计算用户输入的字符串中的单词数:

int count_words(char* text)
{
   int wc = 0;
   for(int i = 0,k = strlen(text); i<k;i++)
   {
      if(strcmp(" ",text[i]) ==0 || strcmp(".",text[i]) ==0 || strcmp("!",text[i]) ==0 || strcmp("?",text[i]) ==0 || strcmp(",",text[i]) ==0)
      {
          wc++;
      }
   }
    return wc+1;
}

但我不断收到此错误:

re.c:59:21: error: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Werror,-Wint-conversion]
      if(strcmp(" ",text[i]) ==0 || strcmp(".",text[i]) ==0 || strcmp("!",text[i]) ==0 || strcmp("?",text[i]) ==0 || strcmp(",",text[i]) ==0)
                    ^~~~~~~
                    &

re.c:59:48: error: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Werror,-Wint-conversion]
      if(strcmp(" ",text[i]) ==0 || strcmp(".",text[i]) ==0 || strcmp("!",text[i]) ==0 || strcmp("?",text[i]) ==0 || strcmp(",",text[i]) ==0)
                                               ^~~~~~~
                                               &

到底发生了什么?

【问题讨论】:

  • text[i] 的数据类型是char,但是strcmp 需要两个const char *,所以你想通过text + i 或等效的&amp;text[i],正如编译器确实建议的那样你。
  • 无论如何,看起来您只是在比较单个字符的字符串,因此您不妨手动检查text[i] == ' ' || text[i] == '.' || ...。您的 strcmp 将始终失败,除非该字符是字符串的最后一个字符,因为 strcmp 会检查 整个 两个字符串是否相等。

标签: c split c-strings function-definition


【解决方案1】:

函数strcmp声明如下

int strcmp(const char *s1, const char *s2);

如您所见,函数的两个参数都有指针类型const char *

但是在这个调用你使用的函数

strcmp(" ",text[i])

第二个参数的类型为char。所以编译器会发出错误信息。

错误:不兼容的整数到指针转换将 'char' 传递给 'const char *' 类型的参数;

你的函数也有逻辑错误。例如,对于一个空字符串,它返回等于1 的字数。

return wc+1;

每个分隔符都算作一个单词。因此,对于仅包含分隔符的字符串,函数会将其解释为包含多个单词。

除此之外,函数count_words 不应更改传递的字符串。它应该被声明为

size_t count_words( const char *text );

函数可以如下定义,如下面的演示程序所示。

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

size_t count_words( const char *text )
{
    const char *separators = " \t.,!?";
    size_t n = 0;
    
    while ( *text )
    {
        text += strspn( text, separators );
        
        if ( *text )
        {
            ++n;
            text += strcspn( text, separators );
        }
    }
    
    return n;
}


int main(void) 
{
    const char *text = "We, beginners, should help each other!";
    
    printf( "There are %zu words in the text \"%s\".", count_words( text ), text );

    return 0;
}

程序输出是

There are 6 words in the text "We, beginners, should help each other!".

更通用的方法是函数的用户可以调用它,自己指定所需的单词分隔符。例如

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

size_t count_words( const char *text, const char *separators )
{
    size_t n = 0;
    
    while ( *text )
    {
        text += strspn( text, separators );
        
        if ( *text )
        {
            ++n;
            text += strcspn( text, separators );
        }
    }
    
    return n;
}

int main(void) 
{
    const char *text = "We, beginners, should help each other!";
    
    printf( "There are %zu words in the string \"%s\".", count_words( text, " \t.,!?" ), text );

    return 0;
}

程序输出同上图

There are 6 words in the text "We, beginners, should help each other!".

【讨论】:

    【解决方案2】:

    strcmp 接受一个以 NULL '\0' 结尾的 char 数组。 对于您的问题,您需要在找到特殊字符时增加字数。 你应该分别检查没有重复的特殊字符。

    /*const special_char[] = {' ','.','!','?',','};*/
    
    int count_words(char* text)
    {
        uint32_t idx = 0;
        int wc = 0;
    
        /*if the first char equal one of special char, don't count that as word*/
        for (int i = 1; i < strlen(text); i++)
        {
            /*Special char shouldn't be repeated respectively otherwise, don't count that as word*/
            if (
                ((' ' == text[i]) || ('.' == text[i]) || ('!' == text[i]) || ('?' == text[i]) || (',' == text[i]))
                && 
                ((' ' != text[i - 1]) && ('.' != text[i - 1]) && ('!' != text[i - 1]) && ('?' != text[i - 1]) && (',' != text[i - 1]))
            )
            {
                wc++;
            }
        }
    
        /*For the last word*/
        wc++;
    
        return wc;
    }
    

    【讨论】:

      【解决方案3】:

      strcmp 接受 char *(字符串)而不是单个 char。最好用strtok`来统计一个字符串的字数。

      这是一个简单的例子

      #include <stdio.h>
      #include <string.h>
      
      int main(void) {
      
        char arr[] = "Temp hello bye! No way. Yes";
        char *delimeters = " !.";
      
        char *token = strtok(arr, delimeters);
        int count = 0;
      
        while (token != NULL) {
          count++;
          token = strtok(NULL, delimeters);
        }
        printf("Words = %d", count);
      
        return 0;
      }
      

      您也可以使用strpbrk 代替strtok

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-23
        • 1970-01-01
        • 2012-07-22
        • 2010-10-04
        • 2012-05-16
        相关资源
        最近更新 更多