K&R Solutions - 1.12

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

A:

#include <stdio.h>

int main(void)
{
  char c;

  while ((c = getchar()) != EOF) {
    if (c == '\t' || c == '\n' || c == ' ') {
      printf("\n");
    } else {
      putchar(c);
    }
  }

  return 0;
}
> muh muh muh     moo cows
muh
muh
muh
moo
cows


18-09-16 Weekly Links




K&R Solutions - 1.11

Q: How would you test the word count program? What kinds of input are most likely to uncover bugs if there are any?


A: There is no perfect answer to this kind of question. Writing good test is really a matter of experience. Part of the reason all programs have bugs is that even the best test writers can't anticipate all the wild ways a program will be used by other people. Nevertheless, writing good tests is a good skill to develop, as you can filter out about 99% of potential bugs that way, and prevent unexpected behaviour when you make small changes to large programs.


The first thing I would do is test it with no characters at all, hoping for '0 0 0'. Next, test it with one word, then with one tab, then with one newline. Then a tab and a newline, then a newline and a tab... you probably don't need the full 16, but instinct tells me that starting input with white space might cause problems. After that, a few short strings like 'two words' will cover the basics. Of course, in real life, I hope I can write such thorough tests.


That might seem like a lot but if you write a test once, you get the peace of mind forever.



K&R Solutions - 1.10

Q: Write a program to copy its input to its output, replacing each tab by \t , each backspace by \b , and each backslash by \\ . This makes tabs and backspaces visible in an unambiguous way.

A:

#include <stdio.h>

int main(void)
{
  char c;

  while ((c = getchar()) != EOF) {
    if (c == '\t') {
      printf("\\t");
    } else if (c == '\b') {
      printf("\\b");
    } else if (c == '\\') {
      printf("\\\\");
    } else {
      putchar(c);
    }
  }

  return 0;
}
tab	example
tab\texample
\ example
\\ example
Backspace example doesn't work!
Backspace example doesn't work!

Denis Richie standing by the computer where he invented C

Notes:

Your terminal emulator takes care of automatically backspacing for you, so the final part of this exercise is long-obsolete.


Explicit backspaces were a problem Richie dealt with when they were developing C and Unix in the 70s. Their office computer didn't have a monitor, only a printer (teletype) which didn't show the characters you had already backspaced (in fact, it added the whitespace \b which was applied as a character deletion only after you saved the line); you just had to try to keep track of your corrections in your head.


According to people around back then, the reason C tends to be so terse, and keywords/variable names tended to be so short, is that backspacing was so frustratingly difficult to keep track of that they wanted to keep the lines as short as possible. This is contrary to the modern style, where clear names are considered extremely important.


It's pretty easy (and fun) to run Unix 6 on an emulator, to get a bit of a taste of what these people were dealing with back then. After trying to write a few small programs, you'll get a pretty good feeling for why old Unix culture discouraged long names.