Theory

From text to number — Atoi and validation

In lesson 5, readInt already turned the user's text into a number — and asked again on bad input. But how does it convert, and what do we do about a number that's a valid integer yet still wrong (like 9999 pages read in a 380-page book)? Let's open it up.

readLine gives you text. "380" is the characters 3, 8, 0 — not the number 380. The translator is strconv.Atoi ("ASCII to integer") — the exact call hiding inside readInt:

import "strconv"

n, err := strconv.Atoi(readLine())
if err != nil {
	fmt.Println("Not a number.")
	continue // ask again — no crash
}

Recognize the shape? It is lesson 3's multiple returns: Atoi returns (value, error). If the text is not a number, err is non-empty and YOU decide what happens next. No crash, no guessing.

Validation rarely ends at err != nil — the value must also fit your rules:

if err != nil || n < 0 || n > it.Pages {
	fmt.Println("Not a valid number of pages.")
	continue
}

"A number" does not yet mean "a valid number": −5 pages read, or 900 out of 380, are errors too.

Tip. err here is just a taste: the full error-handling story (the error type, defer, files) comes in lesson 10. Today the pattern is enough: convert — check — either use it or refuse politely.