Reputation: 13
Not sure why nothing is coming out, compiler finds no errors, it just runs and terminates a few seconds later, no output.
I'll give the source code and the input file's text.
Source code: letterArray.c
#include <stdio.h>
/* displays a histogram of the frequencies
of letters in input */
main()
{
int c, i, nwhite, nother;
int nletter[26];
nwhite = nother = 0;
for (i = 0; i < 26; ++i)
nletter[i] = 0;
while ((c = getchar()) != EOF)
if (c == 'a' || c == 'b' || c ==
'c' || c == 'd' || c == 'e' || c == 'f' ||
c == 'g' || c == 'h' || c == 'i' || c ==
'j' || c == 'k' || c == 'l' || c == 'm' ||
c == 'n' || c == 'o' || c == 'p' || c ==
'q' || c == 'r' || c == 's' || c == 't' ||
c == 'u' || c == 'v' || c == 'w' || c ==
'x' || c == 'y' || c == 'z')
++nletter[c];
else if (c == ' ' || c == '\n' || c
== '\t')
++nwhite;
else
++nother;
printf("Letter: 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
\nOccurences:");
for (i = 0; i < 26; ++i)
printf(" %d", nletter[i]);
printf("\nwhite space = %d, other =
%d\n", nwhite, nother);
}
Text input: input.txt
abcdefg hijklmnop qrstuv wxyzz
I'm pretty new to c, and to programming in general. Any help would be appreciated.
Upvotes: 1
Views: 160
Reputation: 84521
Your compiler should be warning you that the index for your nletter
array will be out of bounds -- which will invoke Undefined Behavior..
The problem causing you to write beyond the bounds of nletter
is your failure to insure the indexing you use runs 0-25
. Specifically you attempt:
++nletter[c];
where c
will contain the ASCII value from 'a' - 'z'
(or 97 - 122
) see: ASCIItable.com. That is well above the usable indexes available (0 - 25
) resulting from your declaration of: int nletter[26];
(recall, arrays are indexed from 0
to n-1
in C).
To prevent writing beyond the bounds of your array, you need to normalize the indexes such that 'a'
will correspond to 0
and 'z'
will correspond to 25
. You do this by simply subtracting 'a'
from the value of c
, e.g.
++nletter[c - 'a'];
although I prefer the post-increment operator here, so:
nletter[c - 'a']++;
(the choice of the increment operator is yours -- the result is the same)
Putting it altogether, and adding a few clean-ups as described in the comments below, you could do something like:
#include <stdio.h>
int main (void) /* main() is a function that return type int */
{
int c, i, nwhite, nother;
int nletter[26] = {0}; /* {0} will initialize nletter */
nwhite = nother = 0;
while ((c = getchar()) != EOF) {
if ('a' <= c && c <= 'z')
nletter[c - 'a']++; /* you want indexes from 0-25 */
else if (c == ' ' || c == '\n' || c== '\t')
nwhite++;
else
nother++;
}
printf ("Letter: 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\n"
"Occurences:");
for (i = 0; i < 26; ++i)
printf ("%2d", nletter[i]); /* use the field-width modifier to */
/* insure output of 2 spaces per-int */
printf("\nwhite space = %d, other = %d\n", nwhite, nother);
return 0;
}
(Note: you can simplify further by including ctype.h
and checking islower(c)
instead of 'a' <= c && c <= 'z'
and using isspace(c)
instead of c == ' ' || c == '\n' || c== '\t'
, but since your Question didn't specify whether you could use anything but stdio.h
I left the manual checks in place.)
Example Use/Output
$ echo "abcdefg hijklmnop qrstuv wxyzz" | ./bin/letterfreq
Letter: 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
Occurences: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2
white space = 4, other = 0
(if testing on windows, omit the quotation marks or you will see other = 2
)
If you are just getting started, then always compile with "warnings-enabled" and read and fix all warnings -- do not accept code until it compiles cleanly -- without a single warning. That will catch most problems before you end up scratching your head for hours. For gcc/clang, that means adding, at minimum, -Wall -Wextra
to your compile string (you can add -pedantic
for a few more, and adding -Wshadow
is helpful). For VS, use /W3
-- the /Wall
for VS contains quite a few non-code related suggestions as warnings.
A compile string for this code would look like:
gcc
gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast -o letterfreq letterfreq.c
VS
cl /nologo /W3 /Ox /Feletterfreq /Tc letterfreq.c
In either case, the code should compile without warning.
Upvotes: 1