【问题标题】:Character counting program, character as ints issue [closed]字符计数程序,字符作为整数问题[关闭]
【发布时间】:2016-06-19 08:53:36
【问题描述】:

if 语句永远不会触发,因此在第二个 for 循环中所有值都打印为 0。

#include <stdio.h>

int main()
{
    char string[100] = "this is A TEST";
    int count[26] = {0};
    int i = 0;

    for(i = 0; string[i] != '\0'; i++){
        if((string[i] + '0') == (i + 97) || (string[i] + '0') == (i + 65)){
            count[i]++;     
        } 
    }

    for(i = 0; i < 26; i++){
        printf("%c: %d \t", i+97, count[i]);

    }

    return 0;
}

【问题讨论】:

  • 添加 '0' 而不是普通的 0,你想达到什么目的?
  • @Pavan 仍然无法正常工作,试图打印出字母 a-z 以及输入字符串中每个字母出现的次数
  • 你想达到什么目的?
  • 停止编写复杂的复合布尔表达式。使用中间临时布尔值,然后您可能有一些机会实际调试自己的代码。另外,学习如何使用括号。
  • 使用ctypes.h。至少不要使用幻数

标签: c arrays for-loop char integer


【解决方案1】:

你的意思好像是这样的

#include <stdio.h>
#include <ctype.h>

int main( void ) 
{
    char string[] = "this is A TEST";
    unsigned int frequency['Z' -'A' + 1] = { 0 };

    for ( const char *p = string; *p; ++p )
    {
        char c = toupper( ( unsigned char )*p );
        if ( c >= 'A' && c <= 'Z' ) ++frequency[c-'A'];
    }

    for ( char c = 'A'; c <= 'Z'; ++c )
    {
        if ( frequency[c-'A'] ) printf( "%c: %u\t", c, frequency[c-'A'] );
    }
    printf( "\n" );
}    

程序输出是

A: 1    E: 1    H: 1    I: 2    S: 3    T: 3

至于你的程序,那么对于初学者来说,这个 if 语句

if((string[i] + '0') == (i + 97) || (string[i] + '0') == (i + 65)){

没有意义。

【讨论】:

    【解决方案2】:

    不要使用像 6597 这样的幻数。请改用字符'A''a'。你必须测试每个char c 是否是一个字母。如果字母为大写字母,则字母中的字符数为c-'A',如果为小写字母,则为c-'a'

    #include <stdio.h>
    
    #define ALPHABET_SIZE ('Z'-'A'+1)
    
    int main (void)
    {
        char string[100] = "this is A TEST";
        int count[ALPHABET_SIZE] = {0};
    
        for ( int i = 0; string[i] != '\0'; i++ ) // for all charecters in the string
        {
            char c = string[i];
            if ( c >= 'A' && c <= 'Z' )           // test if c is uppercase letter
                count[c - 'A'] ++;
            else if ( c >= 'a' && c <= 'z' )      // test if c is lowercase letter
                count[c - 'a'] ++;
        }
    
        for ( int i = 0; i < ALPHABET_SIZE; i++ )
            printf( "%c: %d \t", 'a'+i, count[i] ); 
    
        return 0;
    }
    

    请注意,此代码适用于 ASCII 字符,因为 'A'-'Z''a'-'z' 是连续表示的。

    以下代码适用于任何字符集:

    #include <stdio.h>
    #include <ctype.h>  // toupper, isupper
    #include <limits.h> // UCHAR_MAX 
    
    #define NO_OF_CHAR (UCHAR_MAX+1)
    
    int main (void)
    {
        char string[100] = "this is A TEST";
        int count[ NO_OF_CHAR ] = {0};
    
        for ( int i = 0; string[i] != '\0'; i++ )   // for all charecters in the string      
        {
            unsigned char c = toupper( string[i] );
            count[ c ] ++;                          // increment character counter
        }
    
        for ( int c = 0; c < NO_OF_CHAR; c++ )
        {
            if ( count[c] > 0 && isupper( c ) )
                printf( "%c: %d \n", c, count[c] ); 
        }
        return 0;
    }
    

    【讨论】:

    • 您假设'A'-'Z''a'-'z' 是连续表示的。这不符合C Standard5.2.1 字符集 的标准:执行字符集成员的值是实现定义的。。正如@Olaf 在上面的评论中提到的那样,使用ctypes.h 中提供的isalpha() 等功能。
    • 除了 ASCII 之外,它还适用于比 ASCII 更可能使用的字符集。 (当然,它们是基于 ASCII 的,但你真的需要知道什么时候知道确切的字符集很重要。)很好的答案。
    【解决方案3】:

    以下代码旨在完全符合 C 标准并适用于任何字符集:

    #include <ctype.h>
    #include <limits.h>
    #include <stdio.h>
    
    char string[] = "This is a test.";
    unsigned int frequency[ UCHAR_MAX + 1 ] = { 0 };
    
    int main( void )
    {
        /* this counts ALL characters */
        for ( char *p = string; *p; p++ )
        {
            unsigned char uc = ( unsigned char ) *p;
    
            /* convert letters to upper case */
            uc = toupper( uc );
            ( frequency[ uc ] )++;
        }
    
        for ( int i = 0; i <= UCHAR_MAX; i++ )
        {
            /* output only upper-case results */
            if ( isupper( i ) )
            {
                printf( "Char: %c, frequency: %u\n",
                    ( char ) i, frequency[ i ] );
            }
        }
    
        return( 0 );
    }
    

    【讨论】:

    • @Rabbid76 感谢您指出这一点。固定。
    【解决方案4】:

    代码错误太多,不过下面的sn-p就可以了

    for(i = 0; string[i] != '\0'; i++){
        if(string[i] >=97 && string[i] < 122){
            count[string[i]-97]++;     
        } 
        if(string[i] >=65 && string[i] < 91){
            count[string[i]-65]++;     
        }
    }
    

    首先检查字符串是否包含有效字符, 然后不管你增加它在count数组中的计数的情况

    您需要将字符减少aA的ascii值,具体取决于它是小写还是大写(97 or 65)以获得它的基值。 基值是指它与aA 的位移

    一些输入:尝试使用 hashmap
    始终使用strlen 之类的字符串函数,它可以帮助您执行预定义的操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-18
      • 1970-01-01
      • 2014-02-23
      • 2023-03-15
      相关资源
      最近更新 更多