basics · beginner · ~20 min
Modular arithmetic, character classification, and the negative-modulo trap.
Implement void caesar_shift(char *s, int k) that shifts each ASCII letter in s by k positions, wrapping within its case ('A'..'Z' or 'a'..'z'). Non-letter characters are left unchanged.
k may be any int (positive, negative, or large). Normalise modulo 26.s in place.caesar_shift("abc", 1) -> "bcd"
caesar_shift("xyz", 3) -> "abc"
caesar_shift("Hello, X!", 1)-> "Ifmmp, Y!"
caesar_shift("abc", -1) -> "zab"
caesar_shift("abc", 27) -> "bcd" // 27 % 26 == 1
(c - 'a' + (k % 26 + 26)) % 26).Many real bugs come from forgetting that % in C can return negative values for negative operands — adding + 26 (or whatever the modulus is) before the final % fixes that.
The Caesar cipher is the Hello World of cryptography — never use it for real secrets, but implementing it teaches modular arithmetic over a small alphabet and is great practice with isupper/islower. (Real applications use vetted libraries like libsodium.)
Null-terminated mutable string + shift amount.
s is mutated in place.
ASCII-only. No allocations. Single pass.
void caesar_shift(char *s, int k) { /* TODO */ }
Forgetting that (-1) % 26 == -1 in C — the result must be normalised by adding 26 before the final %. Treating uppercase and lowercase with one branch (causes case-swapping bugs).
Empty string; k == 0; k negative; k > 26.
O(strlen(s)).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.