Saturday, 15 January 2011

The C Programming Language (K&R) 01x0C—Parsing Words—Exercise 1-12

I was listening to a podcast where two “software engineers” talked about their entry into coding and without mentioning the title of the book I know he was referring to “The C Programming Language” by Brian Kernighan and Dennis Ritchie aka K&R. I could be wrong, but it seems likely since its well known in computer coding circles.


K&R Exercise 1-12

Write a program that prints its input one word per line.

I am writing the program from scratch. The input is a character from the keyboard. One character at a time. No strings here. I will use getchar() and putchar() from the standard I/O library. The objective seems straightforward to me. If I come to the end of a word (i.e., whitespace) I shove in a newline character so the next word starts on a new line. One word per line.
 
I am of the habit of writing pseudocode first. I think it’s a good tool.

The Pseudocode:

While not EOF
get character from keyboard
if character is not whitespace, output it
if character is whitespace and previous character is not whitespace, output newline otherwise ignore it

Whitespace will be defined as: space (32), tab (9), newline (10)

I will create a function IsWhitespace to test if it meets the definition. It will return a Boolean. I want to do that because it will make for cleaner code. Plus there is a principle in coding known as the DRY method. Don’t Repeat Yourself. Don’t write the same code over and over. If you use it more than once, put it in a function. Since I see myself needing to test this condition more than once, I’ll create the function. There are other reason for doing it. The definition of whitespace can grow bigger and bigger and an if condition that goes off the page isn’t easy to read.

By the way, we’re never talked about the DRY method in university. We talked about structured programming.

So, I have it worked out. I tested the logic in my head and it makes sense to me. Time to write the code and see if it works. It should.

*          *          *

It didn’t take long to write the code or test it. Using the pseudocode helped. I find it useful in development. I like to add comments even if it’s stating the obvious. Just my current style. It may change. Using the function to test for whitespace also helps. It makes the code cleaner.


Sample Code.

// Function prototypes
bool IsWhitespace(char);

// The standard library includes the system function.
#include <cstdlib>

// C++ standard I/O library.
#include <cstdio>

int main()
{
     // Character input.
     char c = 0;
     // Previous character.
     char prevChar = 0;

     while ((c = getchar()) != EOF) {
           if (IsWhitespace(c))
                if (IsWhitespace(prevChar))
                     // Ignore extra whitespace.
                     ; // Null stmt.
                else
                     // Prev char not whitespace.
                     // Means end of word.
                     // Output new line.
                     putchar(10);
           else
                // Not whitespace, output char.
                putchar(c);

           // Set prev char to current.
           prevChar = c;
     }

     // Keep console window open.
     system("pause");

     // Return some value.
     return 0;
} // end main

bool IsWhitespace(char t)
{

     // Return true for whitespace chars.

     // Space.
     if (t == 32)
           return true;

     // Tab.
     if (t == 9)
           return true;

     // Newline.
     if (t == 10)
           return true;

     // If we get here, no whitespace.
     return false;
}

Note the implementation of the getchar() function has buffering. User input isn’t sent to the program until the return key is entered. That’s why the input shows up twice.


No comments:

Post a Comment