K&R C Exercise 1-10: Make Tabs and Backspaces Visible

Exercise 1-10. 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.

Approach

The exercise is deceptively simple to state but teaches something subtle about C: the difference between a character’s value in the program and its printed representation on screen.

A tab is a single character with ASCII value 9. If you call putchar('t'), the terminal receives one byte and renders it as horizontal whitespace — invisible to the reader. To make that tab visible, you instead print two characters: a backslash followed by the letter t. In a C string literal, the backslash is an escape character, so to get a literal backslash into the string you write \. That makes the printf call printf("\t") — which outputs exactly the two characters t.

The backslash replacement is the most instructive case. A backslash in the input must become two backslashes in the output. You detect a backslash with c == '\' (one backslash, escaped), and you print two with printf("\\") — two escape pairs, each producing one backslash. Every level of interpretation halves the number of backslashes you see in source code.

Solution

/* K&R Exercise 1-10 — make tabs and backspaces visible
 * Compile: gcc -ansi -Wall ex1-10.c -o ex1-10
 */
#include <stdio.h>

int main(void)
{
    int 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;
}

Understanding the Escape Sequences

The table below traces exactly what happens at each stage for the three special characters:

Input character Detected by C source for the print call Characters in that string Output on screen
Tab (ASCII 9) c == 't' printf("\t") backslash, then t t
Backspace (ASCII 8) c == 'b' printf("\b") backslash, then b b
Backslash (ASCII 92) c == '\' printf("\\") backslash, then backslash \

The key rule: in a C string or character literal, \ is the escape sequence for one backslash. So "\\" contains two backslashes and prints as \. Every pair of backslashes in source becomes one backslash at runtime.

A Common Mistake to Avoid

The original exercise trips up students who write c == 'b' or c == 't' instead of c == 'b' and c == 't'. Those are completely different things:

  • 'b' is the letter b (ASCII 98) — a printable character you might type at the keyboard.
  • 'b' is the backspace control character (ASCII 8) — one byte that moves the terminal cursor left.

Similarly, 't' is the letter t (ASCII 116), while 't' is a horizontal tab (ASCII 9). The single quotes and the backslash together form a single-character escape sequence — they are not two separate characters.

Compile and Run

gcc -ansi -Wall ex1-10.c -o ex1-10

The program reads from standard input and writes to standard output. Use shell printf (not echo) to inject actual tab characters into the input stream:

printf "firsttsecondn" | ./ex1-10

You can also run the program interactively: type some text, press Tab in the middle, then press Ctrl+D to signal end-of-file. The program will replay your input with tabs made visible.

Sample Output

A line with two real tabs:

$ printf "onettwotthreen" | ./ex1-10
onettwotthree

A path with backslashes (common on Windows-style paths copied into a C program):

$ printf "C:\Users\alicen" | ./ex1-10
C:\Users\alice

A line with both a tab and a backslash:

$ printf "col1tcol2\valuen" | ./ex1-10
col1tcol2\value

Every real tab becomes the two visible characters t, and every backslash becomes \. Normal printable characters pass through unchanged.

What This Exercise Teaches

  • Escape sequences are C source-level notation, not output. 't' is how you write the tab value (9) in C source. It has nothing to do with the two characters and t that this program prints.
  • Layered escaping. Each layer of interpretation removes one level of backslash escaping. Source \ → runtime string contains → terminal displays . Source \\ → runtime string contains \ → terminal displays \. Count your backslashes carefully.
  • Making invisible characters visible. Tabs, backspaces, and carriage returns are a genuine source of debugging pain — they affect program behaviour (and terminal rendering) without appearing in output. A filter like this one is a practical tool for exposing hidden whitespace in files.
  • The getchar()/putchar() idiom. The while ((c = getchar()) != EOF) loop is the fundamental C I/O pattern, used throughout Chapter 1. This exercise reinforces it with conditional output instead of simple pass-through.

Set Up Your C Environment

To compile and run this solution you need GCC installed. If you haven’t set up C on your machine yet:

← Exercise 1-9  | 
Chapter 1 Solutions  | 
Exercise 1-11 →

Book:

The C Programming Language, 2nd Ed — Kernighan & Ritchie

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>