Exercise 1-10. Write a program to copy its input to its output, replacing each tab by
t, each backspace byb, 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 charactersandtthat 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. Thewhile ((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:
- Complete C Development Environment Setup
- Install GCC on Windows 11
- Install GCC on macOS
- Install GCC on Ubuntu/Linux
- VS Code for C Programming — recommended editor
← Exercise 1-9 |
Chapter 1 Solutions |
Exercise 1-11 →
Book:
The C Programming Language, 2nd Ed — Kernighan & Ritchie