// **************************************************
// Function: getStringStats
//
// Description: analyzes a string and returns counts
//              of different character types
//
// Parameters: s[] - input string
//
// Returns: structure containing all statistics
//
// **************************************************

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

// structure definition
struct stringStats
{
    int totalCharacters; //number of total characters in the string
    int upperCaseCount; // number of upper case characters
    int lowerCaseCount; // number of lower case characters
    int digitCount; // number of digits
    int blankSpaceCount; // number of blank spaces
    int nonAlnumCount; // number of non-alphanumeric characters.
    int vowelCount; // number of vowels (the letters a, e, i, o, u)   ... accept upper and lower case
    int nonVowelCount; // number of non-vowels ... accept upper and lower case
    int specialCharCount; // number of special characters
    int printableNonAlnumCount; // all printable characters that are neither alphanumeric nor a space. For example ‘@’, ‘$’, etc.
    int hexCount; // number of hexadecimal "digits" - 0 through 9 ... and the letters A - F ... accept upper and lower case
    int octalCount; // number of octal "digits" - 0 to 7
    int binaryCount; // number of binary "digits" - 0 or 1
    int punctCount; // number of punctuator characters. Punctuation as defined by this function includes all printable characters that are neither alphanumeric nor a
                    //space. For example ‘@’, ‘$’, etc
    int controlCount; // number of control characters, control characters are those between ASCII codes 0x00 (NUL) and 0x1f (US), plus 0x7f (DEL)
    int printableCount; // number of printable characters, a character is known as printable character if it occupies printing space.
};

// function prototype
struct stringStats getStringStats(char s[]);

int main()
{
    char input[100];
    struct stringStats result;

    // get input
    printf("Enter a string: ");
    fgets(input, sizeof(input), stdin);

    // call function
    result = getStringStats(input);

    // display results
    printf("\nTotal Characters: %d", result.totalCharacters);
    printf("\nUppercase: %d", result.upperCaseCount);
    printf("\nLowercase: %d", result.lowerCaseCount);
    printf("\nDigits: %d", result.digitCount);
    printf("\nBlank Spaces: %d", result.blankSpaceCount);
    printf("\nNon-Alphanumeric: %d", result.nonAlnumCount);
    printf("\nVowels: %d", result.vowelCount);
    printf("\nNon-Vowels: %d", result.nonVowelCount);
    printf("\nSpecial Characters: %d", result.specialCharCount);
    printf("\nPrintable Non-Alnum (not space): %d", result.printableNonAlnumCount);
    printf("\nHex Digits: %d", result.hexCount);
    printf("\nOctal Digits: %d", result.octalCount);
    printf("\nBinary Digits: %d", result.binaryCount);
    printf("\nPunctuation: %d", result.punctCount);
    printf("\nControl Characters: %d", result.controlCount);
    printf("\nPrintable Characters: %d\n", result.printableCount);

    return 0;
}

struct stringStats getStringStats(char s[])
{
	//intialize structure
    struct stringStats st = {0};
    int i;

    //loop to test each character in string
    for(i = 0; s[i] != '\0'; ++i)
    {
        char c = s[i];
        //count the total number of characters
        ++st.totalCharacters;
		//count uppercase 
        if(isupper(c))
        {
        	++st.upperCaseCount;
        }//if
        //count lowercase
        if(islower(c))
        {
        	++st.lowerCaseCount;
        }//if
        //count digits
        if(isdigit(c))
        {
        	++st.digitCount;
        }//if
        //count spaces
        if(isspace(c))
        {
        	 ++st.blankSpaceCount;
        }//if
        //count non alphanumeric characters
        if(!isalnum(c)){
        	 ++st.nonAlnumCount;
        }//if

		//count vowels and non vowels, accepts upper and lowercase
        if(isalpha(c))
        {
            char l = tolower(c);
            if(l=='a'||l=='e'||l=='i'||l=='o'||l=='u')
            {
                ++st.vowelCount;
            }//if
            else
            {
                ++st.nonVowelCount;
            }//else
        }//if

        // count special characters
        if(ispunct(c))
        {
            ++st.specialCharCount;
        }//if

        // counts printable but not alphanumeric and not space
        if(isprint(c) && !isalnum(c) && !isspace(c))
        {
            ++st.printableNonAlnumCount;
            ++st.punctCount;
        }//if
		//count hex digits
        if(isxdigit(c))
        {
        	++st.hexCount;
        }//if
        //count octal digits
        if(c >= '0' && c <= '7')
        {
        	++st.octalCount;
        }//if
        //count binary digits
        if(c == '0' || c == '1')
        {
        	++st.binaryCount;
        }//if
		//count control characters
        if(iscntrl(c))
        {
        	++st.controlCount;
        }//if
        //count printable characters
        if(isprint(c))
        {
        	++st.printableCount;
        }//if

    }//for
	//return structure
    return st;
}