1

Im working on a program for a course, where the program needs to read a single line of a user input and count how many of each letter is in the line. the amount of each letter is put in an array. For example, if the user inputs "Apple" the program should put 1 a, 2 ps, 1 l, and 1 e into the counting array. My problem is that my professor says I cannot use strings in the program.I am unsure of how to store multiple characters so that scanf can read them without using a string. When asking for help, he said to read the input one character at a time.

Ive tried to using scanf within a do-while loop to read each character of the input, but most of my attempts have just ended up with only the first character being read and put into the array which records the number of letters.

printf("ENTER A LINE OF TEXT: \n");
  do {
  scanf("%c ", &userChar);      
  userChar = toupper(userChar);
  userCharVal = userChar;
  histo[userCharVal - 65] = histo[userCharVal - 65] + 1;
  } while(userChar == '\n');

if the user enters "apple", the corresponding array histo[] will be updated based on which letter was typed. i. e. if the user entered apple, the program will first add 1 to histo[0] (corresponding to 'a') and then read the next character of the word. It should end reading the user input at a newline. In reality, the program just records the first character and then ends.

JDNumero
  • 13
  • 3

2 Answers2

1

There are two problems with your code.

First, scanf("%c ", &userChar); will read a single character and then skip any number of whitespace characters that follow. (See this answer for more) By whitespace characters, it usually means ' ', '\t', '\r', '\n', '\v', '\f'. So your userChar will never hold a newline character in your code.

Second, your do-while condition is incorrect. You make it run "while userChar equals a newline character", which is always false, so the loop will never run more than once. The condition you want is userChar != '\n'.

So, try the following:

    printf("ENTER A LINE OF TEXT: \n");
    do
    {
        scanf("%c ", &userChar);
        userChar = toupper(userChar);
        userCharVal = userChar;
        histo[userCharVal - 65] = histo[userCharVal - 65] + 1;
    } while (userChar != '\n');
Ignatius
  • 2,745
  • 2
  • 20
  • 32
1

Your problem is

while(userChar == '\n');

When you read 'A' in "Apple", userChar does not == '\n' causing your oop to terminate after the first iteration. What you intended was:

while(userChar != '\n');

(note the "!=" instead of "==")

With that, your code should work, though it is unnecessary to use a separate userChar and userCharVal.

To clean things up a bit simply use a single int to read the character with getchar(), there is no need for scanf (and it is best avoided). The additional validation needed is that the character is [a-zA-Z] to ensure you are incrementing a valid index with histo[userCharVal - 65]. (and avoid using numbers like 65 when you can use 'A' to clearly indicate what you are doing)

Putting it altogether, you could do something similar to:

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

#define NCHR   26   /* to cover each character in the alphabet */

int main (void) {

    int frequency[NCHR] = {0},  /* frequency of each char initialized to zero */
        c;                      /* character returned by getchar() */

    fputs ("enter a line of text: ", stdout);
    while ((c = getchar()) != '\n' && c != EOF) /* read each char */
        if (isalpha(c))                         /* validate a-zA-Z */
            frequency[toupper(c) - 'A']++;      /* increment element */

    puts ("\nfrequency of characters:\n");
    for (c = 0; c < NCHR; c++)
        if (frequency[c])   /* output lowercase per your example */
            printf (" %c : %d\n", c + 'a', frequency[c]);
}

(note: the additional check against EOF is also required. There is no guarantee of a '\n' The user could generate a manual EOF with Ctrl+d on Linux, or Ctrl+z on windows, to signify end of input, or to cancel input entirely for that matter)

Example Use/Output

$ ./bin/charfreqarray
enter a line of text: Apple

frequency of characters:

 a : 1
 e : 1
 l : 1
 p : 2

Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85