basics · beginner · ~20 min

Caesar cipher (educational toy)

Modular arithmetic, character classification, and the negative-modulo trap.

Challenge

Shift every letter of a string forward in the alphabet by a fixed amount, wrapping around at the ends — the classic Caesar cipher.

Task

Implement void caesar_shift(char *s, int k) that rotates each ASCII letter in s by k positions, wrapping within its own case (A..Z stays uppercase, a..z stays lowercase). Non-letter characters are left exactly as they are. The string is modified in place.

Input

A NUL-terminated, writable string s, and a shift amount int k. k may be positive, negative, or larger than 26 — normalise it modulo 26.

Output

No return value. s is rewritten in place with each letter shifted.

Example

caesar_shift("abc", 1)         ->   "bcd"
caesar_shift("xyz", 3)         ->   "abc"     (wraps past 'z')
caesar_shift("Hello, X!", 1)   ->   "Ifmmp, Y!"
caesar_shift("abc", -1)        ->   "zab"     (negative wraps)
caesar_shift("abc", 27)        ->   "bcd"     (27 mod 26 == 1)

Edge cases

  • Empty string and k == 0 leave the string unchanged.
  • Negative k must wrap correctly — normalise with ((k % 26) + 26) % 26.
  • Digits, punctuation, and whitespace pass through verbatim; case is preserved.

Rules

  • ASCII only, no allocations, single pass.

Why this matters

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.)

Input format

A NUL-terminated writable string s and a shift amount int k (any value).

Output format

No return value; s is shifted in place.

Constraints

ASCII only, no allocations, single pass. Normalise k modulo 26 (handle negatives).

Starter code

void caesar_shift(char *s, int k) { /* TODO */ }

Common mistakes

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).

Edge cases to handle

Empty string; k == 0; k negative; k > 26.

Complexity

O(strlen(s)).

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.