rotone — Shift Letters by One
Allowed functions: write
Write a program that takes a string and displays it, replacing each of its letters by the next one in alphabetical order.
z becomes a and Z becomes A. Case remains unaffected.
The output will be followed by a newline. If the number of arguments is not 1, the program displays a newline.
Examples
$>./rotone "abc"
bcd
$>./rotone "Les stagiaires du staff ne sentent pas toujours tres bon." | cat -e
Mft tubhjbjsft ev tubgg of tfoufou qbt upvkpvst usft cpo.$
$>./rotone "AkjhZ zLKIJz , 23y " | cat -e
BlkiA aMLJKa , 23z $
$>./rotone | cat -e
$
Solution
Download rotone.c#include <unistd.h>
int main(int ca, char **v) {
if (ca != 2) {
write(1, "\n", 1);
return 0;
}
char c;
char *str = v[1];
while (*str) {
c = *str;
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
c = *str + 1 - 26 * (*str % 32 > 25);
write(1, &c, 1);
str++;
}
write(1, "\n", 1);
return 0;
}
How It Works
Goal: Encode a string by shifting each letter one position forward in the alphabet, wrapping 'z' to 'a' and 'Z' to 'A'.
Approach: Add 1 to each letter's ASCII value, and subtract 26 if it would wrap past the end of the alphabet.
Step by step:
- If argument count is not 2, print a newline and exit.
- For each character, check if it is a letter.
- If it is a letter, add 1 to its ASCII value. If the letter's position in the alphabet (
*str % 32) is greater than 25 (i.e., it is 'z' or 'Z'), subtract 26 to wrap back to 'a' or 'A'. - Write the resulting character to stdout.
Key concept: ASCII arithmetic and alphabet wrapping — using % 32 to determine a letter's position and conditionally subtracting 26 to wrap from the end of the alphabet back to the start.