Nearby lessons
66 of 124C - String Input
Reading strings from the keyboard in C — scanf("%s") and why it stops at the first space, fgets() and why it is the safe choice, plus the classic trailing-newline problem and how to fix it.
scanf("%s") — One Word Only
The %s specifier skips leading whitespace, reads characters until the next whitespace, and appends '\0'. Note there is no & — an array name already is an address:
The Space Problem
Type a full name and scanf("%s") takes only the first word. The rest stays in the input buffer waiting for the next read:
fgets() — Read a Whole Line
fgets takes three arguments: the buffer, its size, and the stream. Because you pass the size, it cannot overflow:
Removing the Trailing Newline
fgets stores the Enter key as '\n' inside the string. That extra character breaks comparisons and formatting, so strip it:
How the strcspn Trick Works
strcspn(line, "\n") returns the index of the first newline — or the string's length if there is none. Writing '\0' at that index either replaces the newline or harmlessly rewrites the terminator that is already there. One line, safe in both cases.The older manual version does the same thing with more code:
Mixing scanf and fgets
A scanf("%d") leaves the newline in the buffer, so the next fgets reads an empty line instantly. Clear the buffer between them:
Limiting scanf Safely
If you must use scanf, give %s a width limit — it should be one less than the buffer size to leave room for '\0':
Reading a Line with scanf
A scan set — %[^\n] — reads everything except newline. It works, but fgets is clearer and safer:
Never Use gets()
gets() reads a line but accepts no size limit. Type more than the buffer holds and it overwrites whatever follows in memory. It was deprecated in C99 and removed from the language in C11.
| Function | Reads | Size limit | Verdict |
|---|---|---|---|
scanf("%s") | One word | Only with a width | Use with a width |
scanf("%[^\n]") | A line | Only with a width | Works, awkward |
fgets() | A line | Always | Preferred |
gets() | A line | Never | Removed — never use |
scanf("%s", &name) when name is already an address; expecting scanf("%s") to capture a full name with a space in it; and forgetting that fgets keeps the newline, so strcmp(input, "yes") never matches.- scanf("%s") stops at the first whitespace — one word only.
- Do not put & before a char array in scanf.
- fgets(buf, sizeof(buf), stdin) reads a whole line safely.
- fgets keeps the \n — strip it with strcspn.
- gets() has no size limit and was removed from the C standard.