Exercise 7-1. Write a program that converts upper case to lower or lower case to upper, depending on the name it is invoked with, as found in
argv[0].
Unix convention: a single binary is installed under two names via symlinks (tolower and toupper). argv[0] holds the name used to invoke the program. Checking whether "lower" appears anywhere in argv[0] with strstr handles paths like /usr/bin/tolower and bare tolower alike.
Solution
/* K&R Exercise 7-1 — upper/lower case converter, behaviour set by argv[0]
* Compile: gcc -ansi -Wall ex7-1.c -o tolower
* ln -s tolower toupper
* Usage: ./tolower < input.txt (converts to lower)
* ./toupper < input.txt (converts to upper) */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char *argv[])
{
int c;
int to_lower;
(void)argc;
/* strstr handles full paths: "/usr/bin/tolower" also contains "lower" */
to_lower = (strstr(argv[0], "lower") != NULL);
while ((c = getchar()) != EOF)
putchar(to_lower ? tolower(c) : toupper(c));
return 0;
}
Compile, Link, and Test
gcc -ansi -Wall ex7-1.c -o tolower
ln -s tolower toupper
echo "Hello, World!" | ./tolower # hello, world!
echo "Hello, World!" | ./toupper # HELLO, WORLD!
Expected Output
hello, world! HELLO, WORLD!
Testing without Symlinks
If you don't want to create a symlink, copy and rename:
cp tolower toupper
echo "Hello" | ./toupper # HELLO
Or pass the path directly — since argv[0] is whatever string the shell used to invoke the program:
cp tolower ./tolower_copy
echo "hello" | ./tolower_copy # to_lower = true (contains "lower")
What This Exercise Teaches
argv[0]as program identity — the shell setsargv[0]to the invocation path; a program can inspect this to alter its behaviour, which is how tools likegzip/gunzipandvi/vim/viewshare a single binarystrstrfor substring matching — checking for"lower"as a substring handles./tolower,/usr/bin/tolower, andto_loweruniformly- Conditional expression in
putchar—putchar(to_lower ? tolower(c) : toupper(c))keeps the loop body to a single statement; the direction is decided once before the loop, not on every character
Set Up Your C Environment
← Chapter 6 Solutions |
Chapter 7 Solutions |
Exercise 7-2 →
Book: The C Programming Language, 2nd Ed — Kernighan & Ritchie