25 Input
What to know first
Looking back
Chapter 10 said input, like output, is “a band of characters flowing a line at a time”, and that human input naturally comes in lines ending with Enter (line buffering). Then is the natural unit in which a program takes input also — the line?
A. Exactly so — and that is this chapter’s design principle. A person writes a line and presses Enter. So it follows the grain of the flow for a program to receive a whole line and then find the values it needs inside it. Lifting a line out of the band of characters, and interpreting the lifted line — split those two and each becomes simple.
The need for this chapter, and its context
By the end of this chapter
The questions this chapter answers
- Why split into two stages? I hear there is also a function (
scanf) that reads%dstraight from the input. - How big should the box be?
25.1 Two stages — read, then interpret
The demonstration first. A program that takes one integer from standard input and reports its square. (What was given on standard input for this run is shown in the middle box.)
examples-en/ch25/read.c
#include <stdio.h>
int main(void)
{
char line[100]; /* room for 100 characters — properly explained in chapter 33 */
int n = 0;
fgets(line, sizeof line, stdin); /* step 1: read one whole line */
sscanf(line, "%d", &n); /* step 2: interpret an integer out of that line */
printf("%d squared is %d.\n", n, n * n);
return 0;
}
Given on standard input
7
Output
7 squared is 49.
There are two new faces — one per stage.
Stage 1, fgets — read a whole line. fgets(line, sizeof line, stdin) reads one line from standard input (stdin is its name) and holds it in a space called line. The first line’s char line[100]; is a declaration meaning “take a space of 100 character slots and call it line” — but the formal syntax of a multi-slot space (an array) belongs to chapter 38, so for now know it only as “a container for a line” (a deliberate credit). The second material, sizeof line, is “the number of slots in the container” — a safety device telling fgets the container’s size so that nothing is ever put in past its edge (formal treatment of the sizeof operator is chapter 35).
Stage 2, sscanf — interpret the line we fetched. sscanf(line, "%d", &n) is the partner of chapter 22′s printf — it uses the same format language in the opposite direction. Where printf turned values into characters and sent them out, sscanf finds in the characters (the "7" inside line) a value matching the format (%d) and puts it into a variable. The & before the name is “a mark telling it the place of the variable to put the value in” — the moment addresses, learned in chapter 5, first show their face in the grammar; formal treatment is in chapter 35 (this is Part V’s last deliberate credit).
Q. Why split into two stages? I hear there is also a function (scanf) that reads %d straight from the input.
A. There is, and many primers teach it first — this book takes a different road for two reasons. First, the aftermath of failure is clean. Even if interpretation fails (something that is not a number arrives), the line is already in our own container, so the input band never stops half-way and gets tangled — read directly from the band and fail, and the leftover characters stay caught on the band and contaminate the next read, which is the classic headache of using scanf directly. Second, the grain of safety is the same. Reading a line is a structure in which you tell the container’s size as you read, so overflow is blocked at the source — what accidents the old ways that do not state a size caused, and how this two-stage practice seals them off, is the story of chapter 42. Getting the safe grain into your hands from the start — that is this book’s choice.
25.2 The contract of fgets — what it gives, and what it leaves to you
Know the first stage exactly. fgets promises three things.
| Promise | What it means |
|---|---|
| it will not exceed the box | it was told sizeof line, so it stores no more — overflow is cut off at the root |
| it appends a NUL | so what arrived can be used as a string (chapter 42) |
| it keeps the newline | the \n of the line read is inside the box — stripping it is your job |
Table 25.1
The third bites beginners most often. The listing makes it visible — the newline is printed as @.
examples-en/ch25/lines.c
/* The contract of fgets — what it fills in, and what it does not tell you. */
#include <stdio.h>
#include <string.h>
int main(void)
{
char line[16]; /* deliberately small — to show truncation */
puts("[read one line at a time and echo it back]");
while (fgets(line, sizeof line, stdin) != NULL) {
size_t len = strlen(line);
int has_nl = (len > 0 && line[len - 1] == '\n');
/* make what arrived visible — the newline shown as a mark */
printf(" got: \"");
for (size_t i = 0; i < len; i++)
putchar(line[i] == '\n' ? '@' : line[i]);
printf("\" (%zu bytes, newline at the end: %s)\n",
len, has_nl ? "yes" : "no");
if (!has_nl)
puts(" -> no newline means 'the line was longer than the box and was cut'");
}
puts("\n[two reasons reading ends]");
puts(" fgets returning NULL means 'nothing left (EOF), or an error'.");
puts(" feof and ferror tell them apart; chapter 63 treats them properly.");
return 0;
}
Given on standard input
hi
this line is definitely longer than the box
bye
Output
[read one line at a time and echo it back]
got: "hi@" (3 bytes, newline at the end: yes)
got: "this line is de" (15 bytes, newline at the end: no)
-> no newline means 'the line was longer than the box and was cut'
got: "finitely longer" (15 bytes, newline at the end: no)
-> no newline means 'the line was longer than the box and was cut'
got: " than the box@" (14 bytes, newline at the end: yes)
got: "bye@" (4 bytes, newline at the end: yes)
[two reasons reading ends]
fgets returning NULL means 'nothing left (EOF), or an error'.
feof and ferror tell them apart; chapter 63 treats them properly.
25.2.1 How do you know it was cut?
The middle two lines of the listing answer that. When a line longer than the box arrives, fgets stores only as much as fills the box and returns — and then there is no newline at the end.
| How the box ends | Meaning |
|---|---|
it ends with … \n | one whole line was received |
| it ends with no newline | the line was cut — the rest is still on the band, and the next fgets picks it up |
Table 25.2
That is, “is there a newline at the end?” is the signal of truncation. The listing’s one long line arriving in three pieces is the proof.
Two idioms follow in practice.
line[strcspn(line, "\n")] = '\0'; /* strip the newline if there is one */The first is stripping the newline. That one line is the idiom: strcspn (chapter 42) gives “where the first \n is”, so putting a NUL there removes it. With no newline it points at the end of the string and nothing happens — one line handles both cases.
The second is treating truncation as an error. Let “cut but fine” pass as success and looking up a file under a truncated name follows — chapter 43 treats it properly as one of five disciplines.
Q. How big should the box be?
A. There is no single answer, only a basis for judging.
For a line a person types, be generous — 256 or 1024 are common choices for a name, a path or a command. The listing used 16 deliberately, to show truncation.
Where the line length has no bound, enlarging the box does not end it. Then you check for truncation and join the pieces (calling fgets again), or use a tool that grows the box to the line — POSIX’s getline, which standard C does not have (chapter 66).
One thing to remember: as long as you use a function that takes the size, a box too small causes “truncation”, not “overflow”. Truncation can be checked; overflow brings the program down.
25.3 Interpretation can fail
Unlike output, input has one essentially new problem — you do not know what the other side will send. You expected 7 and seven may arrive. So sscanf’s return value is the number of values successfully interpreted — in the example above, 1 on success and 0 on failure.
As we are now, we have no syntax — branching — for checking that return value and taking one road on success and another on failure. So the example above discarded the return value and laid a floor for the failing case by initialising n to 0 (chapter 23′s habit). The fork appears in the next part (chapter 30), and the discipline of “report failure as a value and always check it” is established formally in chapter 51 — checking input will be that discipline’s first real exercise.
A common misconception. “Input comes from the keyboard”
Mostly it does, but that is not its essence — input comes from the standard input stream (chapter 10). In fact the demonstration just given is the proof: there is nobody striking a keyboard at this book’s example-verification machine — the input7 above was held in a file and flowed onto the band of standard input (redirection). Just as chapter 22′s output is not screen-bound, input is not keyboard-bound, so the same program serves conversation with a person, file processing, and joining programs together, unchanged. The power of the stream design repeats on the input side too.25.4 Closing Part V
We have learned all of how to make names — the name of a value (chapter 23), the name of work (chapter 24), and how to take a value from the outside world and hold it in a name (chapter 25). Chapter 15′s credit ledger is settled, and the credit newly taken is exactly two — the line container (char line[100], in chapter 38) and the place marker (&, in chapter 35) — and both have their due dates written down.
Above all, a program can now converse. Take in, calculate, answer — in the next part we forge the calculation itself: facing the world of integers (chapters 27 and 28), comparing and deciding (chapters 30 and 31), repeating (chapter 32), and completing the meaning of functions (chapter 33). It is the part of values and flow.