From 19fa3daff1447c633029e1730bf0355b21ee029f Mon Sep 17 00:00:00 2001 From: zlg Date: Mon, 26 Nov 2012 20:45:37 -0600 Subject: Solve Exercise 1-21: entab --- 1-20_detab.c | 16 +++++++++++----- 1-21_entab.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 1-21_entab.c diff --git a/1-20_detab.c b/1-20_detab.c index 3101610..e1549e6 100644 --- a/1-20_detab.c +++ b/1-20_detab.c @@ -5,11 +5,15 @@ * "Write a program `detab` that replaces tabs in the input with the proper * number of blanks to space to the next tabstop. Assume a fixed set of * tabstops, say every 'n' columns. Should 'n' be a variable or a symbolic - * parameter? + * parameter?" * * Answer: 'n' should be a symbolic parameter. It's more apparent what's being * worked with and it's not susceptible to scope. Though, in this simple * program it really doesn't matter. + * + * To be correct, this file should use the isprint() function to ensure that + * 'column' only gets incremented when a printable character is being read. I'll + * come back to this when I learn more of the stdlib. */ #define TABWIDTH 8 @@ -30,12 +34,14 @@ int main(void) { ++column; } } else { - // non-tabs simply get output. - putchar(c); - ++column; - // Line-endings should reset the column counter after being output. if (c == '\n') { + // Line-endings should reset the column counter after being output. + putchar(c); column = 0; + } else { + // Now we can just output and increase column! + putchar(c); + ++column; } } } diff --git a/1-21_entab.c b/1-21_entab.c new file mode 100644 index 0000000..595f583 --- /dev/null +++ b/1-21_entab.c @@ -0,0 +1,45 @@ +#include + +/* The C Programming Language: 2nd Edition + * Exercise 1-21: + * "Write a program `entab` that replaces strings of blanks by the minimum + * number of tabs and blanks to achieve the same spacing. Use the same tab + * stops as for `detab`. When either a tab or a single blank would suffice to + * reach a tab stop, which should be given preference?" + * + * Answer: A blank. A tab character that comes after (tabstop - 1) blanks makes + * little-to-no sense and could mess up alignment in some environments. + * + */ + +#define TABWIDTH 8 + +int main(void) { + int c, spaces; + spaces = 0; + while ((c = getchar()) != EOF) { + // Make sure the character is a space... + if (c == ' ') { + ++spaces; + // When spaces is equal to TABWIDTH, we can add a tab + if (spaces == TABWIDTH) { + putchar('\t'); + spaces = 0; + } + } else { + /* As soon as we hit a non-space character, we need to make sure + * there aren't 1-7 spaces leftover. These need to be output before + * we output the non-space character itself! This little loop is + * interesting because it solves the problem of leftover spaces + * _and_ gets the 'spaces' back to zero, which it needs to be once + * we hit a non-space character. + */ + while (spaces != 0) { + putchar(' '); + --spaces; + } + // Output the non-space character. + putchar(c); + } + } +} -- cgit v1.2.3-54-g00ecf