c++countcharc-stringsisalpha

Count how many and what letters contains text


I need to count how many and what letters contains entered text. (take in account case)

I`ve already done similar task with counting numbers in text:


int main()
{
    char text[255];
    int count[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    cin.getline(text, 255);

    int i = 0;
    while (text[i] != '\0')
    {
        switch (text[i])
        {
        case '0': ++count[0];
            break;
        case '1': ++count[1];
            break;
        case '2': ++count[2];
            break;
        case '3': ++count[3];
            break;
        case '4': ++count[4];
            break;
        case '5': ++count[5];
            break;
        case '6': ++count[6];
            break;
        case '7': ++count[7];
            break;
        case '8': ++count[8];
            break;
        case '9': ++count[9];
            break;
        }
        ++i;
    }

    for (int i = 0; i < 10; i++)
    {
        cout << endl << '[' << i << "] = " << count[i];
    }

}

But I wonder if there is a way to do it without writing 52 cases for both uppercase and lowercase letters. I guess I need to use ASCII table, but I cant put it all together.


Solution

  • The simplest way is to use standard C function isalpha and standard container std::map<char, size_t>

    For example

    #include <map>
    #include <cctype>
    
    //...
    
    std::map<char, size_t> alpha;
    
    for ( const char *p = text; *p; ++p )
    {
        if ( std::isalpha( ( unsigned char )*p ) )
        {
           ++alpha[*p];
        }
    }
    
    for ( const auto &item : alpha )
    {
        std::cout << item.first << ": " << item.second << '\n';
    }
    

    Together with counting letters you can count digits. Just change the first for loop the following way

    for ( const char *p = text; *p; ++p )
    {
        if ( std::isalpha( ( unsigned char )*p ) || std::isdigit( ( unsigned char )*p ) )
        {
           ++alpha[*p];
        }
    }