1

I am working on a program that counts the number of characters in a string. It also counts and reports the number of times that each letter (a-z) is used. For reasons I can't figure out my program will only count and return lowercase letters.

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


int main()
{
    char string[100];
    int c = 0, count[26] = {0}, x, charcount = 0;

    printf("Enter a string\n");
    gets(string);


    while (string[c] != '\0')
    {
        if (string[c] >= 'a'||'A' && string[c] <= 'z'||'Z')
        {
            x = string[c] - 'a';
            count[x]++;
        }
        c++;
    }
    for(c = 0; c < strlen(string); c++)
    {
        if(string[c] !=' ')
        {
            charcount++;

        }
    }
    printf("The string %s is %d characters long.\n", string, charcount);


    for (c = 0; c < 26; c++)
    {
        if(count[c] != 0)
            printf("%c %d \n", c + 'A', count[c]);


    }



    return 0;
}

Anyone know what I am doing wrong here?

  • 1
    I see `x = string[c] - 'a'` for lowercase; where’s the handling of uppercase? `string[c] >= 'a'||'A' && string[c] <= 'z'||'Z'` doesn’t work, but if it did, it still wouldn’t convert uppercase to lowercase. – Ry- May 11 '20 at 04:18
  • 1
    Does this answer your question? [How do I lowercase a string in C?](https://stackoverflow.com/questions/2661766/how-do-i-lowercase-a-string-in-c) – Daniel Brose May 11 '20 at 04:25
  • 1
    You want the `isalpha()` function in `ctypes.h`. Your logic for testing string[c] is all wrong. – jwdonahue May 11 '20 at 04:28
  • 1
    See also, `isupper()`, `islower()` and `isspace()`. – jwdonahue May 11 '20 at 04:30
  • Thank you -Ry-, I added a conditional for statement for upper case and it worked! – William Hamilton May 11 '20 at 04:48
  • Tip - important: Enable compiler warnings at a high level and make sure to fix all warnings **before** running the program. Had you done that, the compiler would have pointed you to the bad if-statement and you could have fixed it. For gcc you could do: `-Wall -Wextra -Werror` – Support Ukraine May 11 '20 at 04:56
  • 1
    You know -- a very handy way to handle collecting the count of all types of characters (upper, lower,, digits, whitespace, punctuation, control, etc...) is simply to create a frequency array for each category of character you want to count. Simply create and initialize your arrays all zero and then use an index that maps the character to one of the elements of the array, e.g. `if (isupper(c)) upper[c - 'A']++;` and so on. – David C. Rankin May 11 '20 at 05:07
  • OT regarding: `gets(string);` the function: `gets()` has been depreciated for years and completely removed from the C language around 2009. Suggest using `fgets()` (which has a different set of parameters, so be sure to read the MAN page for `fgets()` – user3629249 May 12 '20 at 14:27
  • OT: regarding: `for(c = 0; c < strlen(string); c++)` The function: `strlen()` returns a `size_t ` (unsigned long int) but the variable `c` is declared as an `int`. The result is comparing a unsigned value with a signed value. Probably ok for small values, but becomes a problem for large numbers and for negative values – user3629249 May 12 '20 at 14:29

2 Answers2

4

This:

if (string[c] >= 'a'||'A' && string[c] <= 'z'||'Z')

doesn't work. I won't try to explain what this is actually doing, but suffices to say it isn't what you meant.

In C you need to do one logic operation at a time, and then do another logic operation with the results.

This is what you meant:

if ((string[c] >= 'a' && string[c] <= 'z') || (string[c] >= 'A' && string[c] <= 'Z'))

Which could be simplified using the tolower (or toupper) function from the ctype.h library:

#include <ctype.h>

//...

if (tolower(string[c]) >= 'a' && tolower(string[c]) <= 'z')

Or better yet, simply use the isalpha function from the ctype.h library to verify that the character is a letter:

#include <ctype.h>

//...

if (isalpha(string[c]))

And there is another problem here:

x = string[c] - 'a';

You need to convert the letter to lowercase before subtracting 'a', so again we can use tolower:

x = tolower(string[c]) - 'a';
isrnick
  • 621
  • 5
  • 12
3

This line of your code is seriously broken:

if (string[c] >= 'a'||'A' && string[c] <= 'z'||'Z')

If should be:

if ( ((string[c] >= 'a') && (string[c] <= 'z')) || ((string[c] >= 'A') && (string[c] <= 'Z'))

But that whole mess can be replaced with:

#include <ctype.h>
....
if (isalpha(string[c]))
jwdonahue
  • 6,199
  • 2
  • 21
  • 43