Thread: K&R Exercise 1-14 - Looking for Critique

  1. #1
    Registered User edw211's Avatar
    Join Date
    Jun 2011
    Location
    Wilkes-Barre, PA
    Posts
    22

    K&R Exercise 1-14 - Looking for Critique

    Hello all,

    I'm currently working my way through the K&R book and am doing all the exercises as I come across them. This exercise asks me to write a program that prints out a histogram of the number of occurrences of each character in the input. I should note that on the x-axis, I list the ASCII codes of each character that appears in the file because it seemed the most consistent way to display the data while also including whitespace characters.

    Here is my code:

    Code:
    /* Corresponding K&R section: 1.6 */
    
    /* Counts frequencies of different characters in input */
    
    #include <stdio.h>
    
    #define NUM_CHARS 256
    
    int main(void)
    {
    	int c = 0;
    	int charFrequencies[NUM_CHARS] = {0};
    	int maxFrequency = 0;
    
    	/* -------------- Get Frequency Data --------------- */
    
    	while((c = getchar()) != EOF)
    		charFrequencies[c]++;
    	
    	/* --------------- Print Histogram ----------------- */
    
    	/* NOTE: characters not appearing in the input will not
    			 appear on the x-axis. To allow display of data
    			 for non-printable characters, ASCII codes will
    			 be used on the x-axis. */
    
    	//Determine max frequency
    	for(c = 0; c < NUM_CHARS; c++) 
    	{
    		if(charFrequencies[c] > maxFrequency)
    			maxFrequency = charFrequencies[c];
    	}
    	
    	//print y-axis and bars
    	int i = 0;
    	printf("\n\n");
    	for(c = maxFrequency; c > 0; c--)
    	{
    		printf("%7d | ", c);
    		for(i = 0; i < NUM_CHARS; i++)
    		{
    			if(charFrequencies[i] >= c)
    				putchar('*');
    			/* To align with the x-axis, only print
    				a space if the character appears in
    				the input */
    			else if(charFrequencies[i] > 0)
    				putchar(' '); 
    		}
    		putchar('\n');
    	}
    
    	//print x-axis
    
    	//print dashes
    	printf("        +-");
    	for(i = 0; i < NUM_CHARS; i++)
    	{
    		if(charFrequencies[i] > 0)
    			putchar('-');
    	}
    	putchar('\n');
    
    	//print 100s digit of ASCII code
    	printf("          ");
    	for(i = 0; i < NUM_CHARS; i++)
    	{
    		if(charFrequencies[i] > 0)
    			printf("%d", i / 100);
    	}
    	putchar('\n');
    
    	//print 10s digit of ASCII code
    	printf("          ");
    	for(i = 0; i < NUM_CHARS; i++)
    	{
    		if(charFrequencies[i] > 0)
    			printf("%d", (i % 100) / 10);
    	}
    	putchar('\n');
    
    	//print 1s digit of ASCII code
    	printf("          ");
    	for(i = 0; i < NUM_CHARS; i++)
    	{
    		if(charFrequencies[i] > 0)
    			printf("%d", (i % 100) % 10);
    	}
    	printf("\n\n");
    
    	return 0;
    }
    I realize I am not using certain library functions that would help condense this code, but part of the challenge of the exercises is to implement a solution using only the components of the C language that I've been exposed to thus far. I'm mainly looking for comment on how well my solution scales with size of input, or if there are any known bad habits I'm indulging in.
    Evan Williams
    Lehigh University Senior
    Computer Science and Engineering

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Everything looks good, with the possible exception of turning "(i % 100) % 10" into just "i % 10".

  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    As long as it's giving you the right answers, I'd say you're doing just fine.

    Nice text setup ... better than mine when I started.

  4. #4
    Registered User edw211's Avatar
    Join Date
    Jun 2011
    Location
    Wilkes-Barre, PA
    Posts
    22
    Quote Originally Posted by tabstop View Post
    Everything looks good, with the possible exception of turning "(i % 100) % 10" into just "i % 10".
    Ohhh yeah, right you are. Not sure why I did that.

    And thanks, CommonTater.

    One other question. I've been defaulting to using putchar() if I only need a single character because I'm assuming it's faster than printf(), given that printf() has to check for and deal with format strings. Is that true?
    Evan Williams
    Lehigh University Senior
    Computer Science and Engineering

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    In the work you're doing I doubt it makes much difference, maybe a couple of microseconds. There is some value in knowing the library functions, even the less-used ones, so no big deal far as I can tell.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by edw211 View Post
    One other question. I've been defaulting to using putchar() if I only need a single character because I'm assuming it's faster than printf(), given that printf() has to check for and deal with format strings. Is that true?
    Technically, yes, putchar would be faster. It only has one char to output, not a string that has an extra char (the null), and that has to be checked for format characters. As long as you're using a string literal like printf("\n") however, most modern compilers will optimize that into a putchar. The compiler can't necessarily do the same for the following code however:
    Code:
    char *s;
    // do a bunch of stuff with s, eventually making it contain "\n"
    printf(s);

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by edw211 View Post
    One other question. I've been defaulting to using putchar() if I only need a single character because I'm assuming it's faster than printf(), given that printf() has to check for and deal with format strings. Is that true?
    Technically, yes, putchar would be faster. It only has one char to output, not a string that has an extra char (the null), and that has to be checked for format characters. As long as you're using a string literal like printf("\n") however, most modern compilers will optimize that into a putchar. The compiler can't necessarily do the same for the following code however:
    Code:
    char *s;
    // do a bunch of stuff with s, eventually making it contain "\n"
    printf(s);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another K&R Exercise... Looking for a critique
    By edw211 in forum C Programming
    Replies: 8
    Last Post: 06-08-2011, 09:41 PM
  2. Critique my program
    By Jason Spaceman in forum C Programming
    Replies: 6
    Last Post: 10-26-2004, 05:38 PM
  3. could ya'll critique this code
    By linuxdude in forum C Programming
    Replies: 0
    Last Post: 02-19-2004, 09:55 PM
  4. C 101 critique, please?
    By adobephile in forum C Programming
    Replies: 13
    Last Post: 01-01-2003, 07:05 PM
  5. critique me please
    By ober in forum A Brief History of Cprogramming.com
    Replies: 13
    Last Post: 10-02-2002, 01:59 PM