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

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

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

   while ( string[c] != '\0' )
   {

      if ( string[c] >= 'a' && string[c] <= 'z' ){
         count[string[c]-'a']++;
         accum++;
      }

      else if (string[c] >= 'A' && string[c] <= 'Z'){
          count[string[c]-'A']++;
          accum++;
      }
      c++;
   }

   for ( c = 0 ; c < 26 ; c++ )
   {
      if( count[c] != 0 )
          printf( "%c %f\n", c+'a', ((double)count[c])/accum);
   }

   return 0;
}

This should be an easy question, but I can't seem to get it to work. Right now, I have the print statement "Enter a string". I want to change it so that the user can keep inputting a string using scanf instead of printf until EOF is reached. Basically I want to remove the "Enter a string" statement and just have input a string until EOF and then have the letter frequency run once on all the strings inputted. How would I do that?

user3880587
  • 69
  • 2
  • 12
  • Do you mean you want behavior similar to what you'd get if this were run over and over until EOF (of the console?), but only needing to run the program once? – Scott Hunter Oct 27 '14 at 19:07
  • Basically the program is to keep inputting strings using scanf until EOF and then count the letter frequencies of all the strings inputted. – user3880587 Oct 27 '14 at 19:18
  • 1
    never, ever, use `gets`. This dangerous and has been withdrawn from POSIX and C standards. Use `fgets`, instead. – Jens Gustedt Oct 27 '14 at 19:24
  • this line: ((double)count[c])/accum) is dividing a smaller number by the total number of numbers. I.E. the result would be less than one. However this code is using an integer divide, so when ever the divisor is greater than the divided, the result will always be 0 – user3629249 Oct 27 '14 at 21:02

3 Answers3

1

To do this using scanf() for input.

scanf() returns EOF when the EOF condition or IO error occurs.

 // printf("Enter a string\n");
 char ch;
 while (scanf("%c", &ch) == 1) {  
   if ( ch >= 'a' && ch <= 'z' ){
     count[ch-'a']++;
     accum++;
   }
   ...
 }

Using int ch = fgetc(stdin) would make more sense.


"The fscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed. Otherwise, the function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure." C11dr §7.21.6.2 16

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Add your printf and gets statements inside the while loop

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

while ( string[c] != '\0' )
{
     ...//remaining code inside while loop

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

}
... //for loop code and return 0;
StormeHawke
  • 5,987
  • 5
  • 45
  • 73
userDEV
  • 495
  • 4
  • 18
0

Here you go. I zeroed the variables for each loop. And I treated a blank entry (just press Enter) as EOF. But if you wanted the statistics for all the strings, don't zero the values at the start of the while loop

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


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

    do {
        c = 0;
        accum = 0;
        memset (count, sizeof count, 0);

        gets(string);
        if (strlen (string) < 1)
            break;      // terminate

        while ( string[c] != '\0' ) {
            if ( string[c] >= 'a' && string[c] <= 'z' ) {
                count[string[c]-'a']++;
                accum++;
                }

            else if (string[c] >= 'A' && string[c] <= 'Z') {
                count[string[c]-'A']++;
                accum++;
                }
            c++;
            }

        for ( c = 0 ; c < 26 ; c++ ) {
            if( count[c] != 0 )
                printf( "%c %f\n", c+'a', ((double)count[c])/accum);
            }
        }
    while (1);

    return 0;
}
Weather Vane
  • 33,872
  • 7
  • 36
  • 56