K&R2 Ex1-14

I

ilan pillemer

Hi,

I have made an attempt at exercise 1.14 in K&R2: namely;

"Write a program to print a histogram of the frequencies of different
characters in its input."

Here is my program and the output.

#include <stdio.h>
#define HISTHEIGHT 400

int main()
{
int c, i, j, tot;
int nchars[26];

for (i = 0; i < 26; i++)
nchars = 0;

tot = 0;
while ((c = getchar()) != EOF) {
if ((c - 'A') >= 0 && (c-'A') <= 26) {
nchars[c - 'A']++;
tot++;
}
else if ((c - 'a') >= 0 && (c - 'a' <=26)) {
nchars[c-'a']++;
tot++;
}
}

/* Turn into a value out of HISTHEIGHT so it will fit screen */
/* when printing character frequencies as a histogram */

for (i = 0; i < 26; i++)
nchars = ( nchars * HISTHEIGHT ) / tot;

for (i = HISTHEIGHT; i > 0; i--) {
for (j = 0; j < 26; j++)
if (nchars[j] >= i)
printf("***");
else
printf(" ");
printf("\n");
}

printf(" 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");
return 0;
}

***************************OUTPUT*********************
[ilan@pillemer Ch1]$ ./a.out < /usr/share/dict/words



***
***
***
***
***
***
***
***
***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** *** ****** ***
*** *** *** ****** ******
*** *** *** ****** ******
*** *** *** ****** *********
*** *** *** ****** *********
*** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** *** ****** *********
*** *** *** *** *** ****** *********
*** ********* *** *** ****** ************
*** ********* *** *** ****** ************
*** ********* *** *** ********* ************
*** ********* ****** *************** ************
*** ********* ****** *************** ************
*** ********* ********* *************** ************
*** ********* ********* *************** ************
*************** ********* *************** ************ ***
*************** ********* *************** ************ ***
*************** ********* *************** ************ ***
*************************** *************** ************ ***
*************************** ****************** ****************** ***
*************************** ****************** ****************** ***
*************************** ****************** ***************************
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
[ilan@pillemer Ch1]$
 
B

Barry Schwarz

Hi,

I have made an attempt at exercise 1.14 in K&R2: namely;

"Write a program to print a histogram of the frequencies of different
characters in its input."

Here is my program and the output.

#include <stdio.h>
#define HISTHEIGHT 400

int main()
{
int c, i, j, tot;
int nchars[26];

for (i = 0; i < 26; i++)
nchars = 0;

tot = 0;
while ((c = getchar()) != EOF) {
if ((c - 'A') >= 0 && (c-'A') <= 26) {


A couple of issues:

Not all character sets have the alphabet in consecutive
characters. For example, EBCDIC used on IBM mainframes has seven
non-alphabetic characters between I and J.

When c-'A' is equal to 26, you attempt to increment nchars[26].
There is no such element of the array. The elements run from [0] to
[25] inclusive.
nchars[c - 'A']++;
tot++;
}
else if ((c - 'a') >= 0 && (c - 'a' <=26)) {
nchars[c-'a']++;
tot++;
}
}

/* Turn into a value out of HISTHEIGHT so it will fit screen */
/* when printing character frequencies as a histogram */

for (i = 0; i < 26; i++)
nchars = ( nchars * HISTHEIGHT ) / tot;


An interesting interpretation of the requirement. Every other attempt
I have seen produced actual counts, not relative frequencies.
for (i = HISTHEIGHT; i > 0; i--) {
for (j = 0; j < 26; j++)
if (nchars[j] >= i)
printf("***");
else
printf(" ");
printf("\n");
}

printf(" 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");
return 0;
}


Remove del for email
 
R

Richard Heathfield

ilan pillemer said:
Hi,

I have made an attempt at exercise 1.14 in K&R2: namely;
while ((c = getchar()) != EOF) {
if ((c - 'A') >= 0 && (c-'A') <= 26) {

How does this program cope on IBM mainframes? Badly, I suspect.
 
M

Malcolm McLean

ilan pillemer said:
Hi,

I have made an attempt at exercise 1.14 in K&R2: namely;

"Write a program to print a histogram of the frequencies of different
characters in its input."

Here is my program and the output.

#include <stdio.h>
#define HISTHEIGHT 400

int main()
{
int c, i, j, tot;
int nchars[26];

for (i = 0; i < 26; i++)
nchars = 0;

tot = 0;
while ((c = getchar()) != EOF) {
if ((c - 'A') >= 0 && (c-'A') <= 26) {
nchars[c - 'A']++;
tot++;
}
else if ((c - 'a') >= 0 && (c - 'a' <=26)) {
nchars[c-'a']++;
tot++;
}
}

/* Turn into a value out of HISTHEIGHT so it will fit screen */
/* when printing character frequencies as a histogram */

for (i = 0; i < 26; i++)
nchars = ( nchars * HISTHEIGHT ) / tot;

for (i = HISTHEIGHT; i > 0; i--) {
for (j = 0; j < 26; j++)
if (nchars[j] >= i)
printf("***");
else
printf(" ");
printf("\n");
}

printf(" 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");
return 0;
}

***************************OUTPUT*********************
[ilan@pillemer Ch1]$ ./a.out < /usr/share/dict/words



***
***
***
***
***
***
***
***
***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** *** ****** ***
*** *** *** ****** ******
*** *** *** ****** ******
*** *** *** ****** *********
*** *** *** ****** *********
*** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** ****** *********
*** *** *** *** *** ****** *********
*** *** *** *** *** ****** *********
*** ********* *** *** ****** ************
*** ********* *** *** ****** ************
*** ********* *** *** ********* ************
*** ********* ****** *************** ************
*** ********* ****** *************** ************
*** ********* ********* *************** ************
*** ********* ********* *************** ************
*************** ********* *************** ************
***
*************** ********* *************** ************
***
*************** ********* *************** ************
***
*************************** *************** ************
***
*************************** ****************** ******************
***
*************************** ****************** ******************
***
*************************** ******************
***************************
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
[ilan@pillemer Ch1]$

Good first attempt.
However as Richard Heathfield pointed out, this program assumes that A to Z
are contiguous in memory. On some machines that don't use ASCII this is not
the case.
So why not write a function

/*
Convert to character to index 0 - 25
Params: ch - character to convert
Returns: index, or -1 if not an upper case character.
*/
int chtoindex(char ch)
{
char *upper = "ABCDEFGHIJKLMNOPQRSTUVWYZ";
/* code here */
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top