Exercise 1-19. Write a function
reverse(s)that reverses the character strings. Use it to write a program that reverses its input a line at a time.
Approach
The core algorithm is the classic two-pointer swap: place one index at the start of the string (i = 0) and one at the end (j = last character), swap those two characters, move both pointers toward the middle, and repeat until they meet or cross. It is an in-place reversal — no second array is needed, only a single temporary variable.
The one trap K&R plants here is the \n stored at the end of each line. Because getline2 saves the newline before the null terminator, a naive reversal of "hello\n" would produce "\nolleh" — the newline moves to the front and every line begins with a blank line. The fix is to detect the trailing \n and step j back one position past it before starting the swap loop, leaving the newline anchored where printf expects it.
Solution
/* K&R Exercise 1-19: reverse each input line
Compile: gcc -ansi -Wall exercise1-19.c -o exercise1-19 */
#include <stdio.h>
#define MAXLINE 1000
int getline2(char line[], int maxline);
void reverse(char s[]);
int main(void)
{
char line[MAXLINE];
while (getline2(line, MAXLINE) > 0) {
reverse(line);
printf("%s", line);
}
return 0;
}
/* getline2: read a line into line[], return length */
int getline2(char line[], int maxline)
{
int c, i;
for (i = 0; i < maxline - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
line[i] = c;
if (c == '\n')
line[i++] = '\n';
line[i] = '\0';
return i;
}
/* reverse: reverse the string s[] in place */
void reverse(char s[])
{
int i, j;
char temp;
/* walk j to the last character before '\0' */
for (j = 0; s[j] != '\0'; ++j)
;
--j;
/* skip trailing newline so it stays at the end */
if (s[j] == '\n')
--j;
/* swap from both ends toward the middle */
for (i = 0; i < j; ++i, --j) {
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
Compile and Run
gcc -ansi -Wall exercise1-19.c -o exercise1-19
./exercise1-19
Type a line and press Enter. The program immediately prints it reversed. Press Ctrl+D (Unix/macOS) or Ctrl+Z then Enter (Windows) to end input. You can also pipe input directly:
echo "Hello, World!" | ./exercise1-19
printf "racecar\nabc\n" | ./exercise1-19
Sample Output
$ printf "Hello, World!\nracecar\na\n" | ./exercise1-19 !dlroW ,olleH racecar a
"racecar" is a palindrome — it reads the same forwards and backwards, so it appears unchanged. A single-character line like "a" is trivially its own reverse.
How the Two-Pointer Swap Works
Tracing reverse on "Hello\n", stored as H e l l o \n \0 at indices 0–6:
- The
forloop advancesjuntils[j] == '\0', leavingj = 6. Then--jgivesj = 5, pointing at\n. s[5] == '\n', sojbecomes4, pointing ato. The newline is now outside the swap range.- Iteration 1 —
i = 0, j = 4: swapH↔o→o e l l H \n \0 - Iteration 2 —
i = 1, j = 3: swape↔l→o l l e H \n \0 - Iteration 3 —
i = 2, j = 2:i < jis false, stop. The middlelneeds no swap. - Result:
"olleH\n"— correct output with newline still at the end.
The i < j condition handles both even- and odd-length strings correctly. When the indices cross (even length) or meet (odd length), every character has already been placed in its final position.
What This Exercise Teaches
- Two-pointer technique: working inward from both ends of an array is a pattern that reappears constantly — in binary search, palindrome checking, partitioning, and more. This exercise is its simplest form.
- The temp-variable swap:
temp = s[i]; s[i] = s[j]; s[j] = temp;is the fundamental way to exchange two values in C. Withouttemp, the first assignment would overwrite the value you still need. - In-place algorithms: this reversal uses O(1) extra space — just one
char temp— regardless of string length. No second array is allocated. - Newline anchoring: any function that operates on lines stored by
getlinemust handle the embedded\ndeliberately. Forgetting it produces subtly wrong output that looks almost right until you look carefully. - Separating concerns:
getline2handles I/O;reversedoes one job. This clean split between reading data and processing it is the K&R approach to program structure, even at the simplest level.
Set Up Your C Environment
To compile and run this solution you need GCC installed. If you haven’t set up C development on your machine yet:
- Install GCC on Windows 11
- Install GCC on macOS
- Install GCC on Ubuntu/Linux
- VS Code for C Programming — recommended editor
- Best Online C Compilers — no installation needed
← Exercise 1-18 |
Chapter 1 Solutions |
Exercise 1-20 →
Book:
The C Programming Language, 2nd Ed — Kernighan & Ritchie