I have written a program in C running on UNIX which counts the number of each letters in a input text file. For a file like this:
‘The cat sat on the green mat’
The output would be like this:
The letter ’a’ occurs 3 times.
The letter ’c’ occurs 1 times.
The letter ’e’ occurs 4 times.
The letter ’g’ occurs 1 times.
The letter ’h’ occurs 2 times.
The letter ’m’ occurs 1 times.
The letter ’n’ occurs 2 times.
The letter ’o’ occurs 1 times.
The letter ’r’ occurs 1 times.
The letter ’s’ occurs 1 times.
The letter ’t’ occurs 5 times.
5 *
4 * *
4 * *
3 * * *
3 * * *
2 * * * * *
2 * * * * *
1 * * * ** *** ***
1 * * * ** *** ***
0 **************************
0 **************************
... abcdefghijklmnopqrstuvwxyz
Where the graph represents the amount of times a letter appears. (If it is more than 10, i simply put a ‘+’ after the 10th row). The code I’ve currently written to achieve this is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void drawGraph(int letters[26], char alpha[26]);
void printLetters(int letters[26], char alpha[26]);
void getLetters(FILE *fp, int letters[26], char alpha[26]);
int main(int argc, char *argv[]) {
FILE *fp;
int letters[26] = { 0 };
char alpha[26] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z' };
int indexedAlpha[256] = { 0 };
int j = 1;
for (i = 97; i <= 127; i++)
{
indexedAlpha[i] = j;
j++;
}
//open file
if ((fp = fopen(argv[1], "r")) == NULL)
{
perror("Cannot open file");
exit(EXIT_FAILURE);
}
getLetters(fp, letters, alpha);
printLetters(letters, alpha);
printf("\n");
drawGraph(letters, alpha);
printf("\n");
return EXIT_SUCCESS;
}
void getLetters(FILE *fp, int letters[26], char alpha[26]) {
int c;
for (int i = 0; (c = fgetc(fp)) != EOF; i++)
{
c = fgetc(fp);
if ( isalpha(c) )
{
for ( int j = 0; j < 26; j++ ) //find which letter it is
{
if( c == alpha[j] )
{
letters[j]++;
break;
}
}
}
}
}
void printLetters(int letters[26], char alpha[26]) {
for( int i = 0; i < 26; i++ )
{
if(letters[i] != 0){
printf("The letter '%c' occurs %d times.\n", alpha[i], letters[i]);
}
}
}
void drawGraph(int letters[26], char alpha[26]) {
int x = 11;
int y;
while(x >= 0)
{
y = 0;
while (y < 2)
{
if (x == 10)
{
printf(" %d ", x);
}
else if (x == 11)
{
printf(" ");
}
else
{
printf(" %d ", x);
}
for( int i = 0; i < 26; i++ )
{
if(letters[i] > 10)
{
printf("+");
letters[i] = 10;
y++; // Break out of while loop
}
else if(letters[i] == x)
{
printf("*");
}
else
{
printf(" ");
}
if (letters[i] == x && y == 1)
{
letters[i] = letters[i] - 1;
}
}
printf("\n");
y++;
}
x--;
}
printf("... ");
for( int i = 0; i < 26; i++ )
{
printf("%c", alpha[i]);
}
}
However my current code has two problems.
1. I always print out 10 Y-axis points i want to only print out as many Y-axis points as needed, What would be the best way to achieve this?
2. Currently only lower case characters are counted, how can i address this?
Also any notation or better methodology would be much appreciated, Im still trying to learn!
Thanks!
2nd question seems bit easy to me :
make an structure like this :
In this way you can keep track of each letter with it’s count.
To print “histogram” of each alphabet in file you need
(11 + 1 + 1)lines(means at least 13 lines , can be extra lines for separating characters and their bar )
11lines for11times occurrence of alphabet and1for+as mentioned and1for alphabets itself.But to print these lines, You need to take care of extra things about the space before the each of the
*(histogram symbol you used).So, loop through the array and print it like, For your
1st questiontry something like this: