Step 7 of 7
One character at a time
scanf reads numbers and words. Sometimes you want the raw text instead, one character at a time: counting lines, copying input, cleaning up spacing, or writing your own parser. getchar() (from <stdio.h>) returns the next character of input, and putchar(c) prints one.
When the input runs out, getchar() returns the special value EOF ("end of file", a negative number, usually -1). So the classic loop reads until then:
#include <stdio.h>
int main(void) {
int c;
int chars = 0, lines = 0;
while ((c = getchar()) != EOF) {
chars++;
if (c == '\n') {
lines++;
}
}
printf("%d characters, %d lines\n", chars, lines);
return 0;
}
gg
wp
6 characters, 2 lines
How it works
(c = getchar()) != EOFdoes two things: it stores the next character inc, then compares it withEOF. The inner parentheses are required, because!=binds tighter than=: without them,cwould get the result of the comparison (0 or 1) instead of the character.- The newline at the end of each line is a character too (
'\n'), which is why two 2-letter lines count as 6 characters. cis anint, not achar, and this matters.getchar()must be able to return every possible byte value andEOF, which is one more value than acharcan hold. Withchar c, either the loop never ends (on systems wherecharcan't be negative) or a real byte with value 255 is mistaken for the end of input.
Where does input end?
On this site the input is everything in the input box, so it ends when that text ends. When you run a program in a terminal and type the input yourself, you signal the end with Ctrl+D on Linux and macOS, or Ctrl+Z then Enter on Windows. When input comes from a file (./program < data.txt), it ends at the end of the file.
Remembering the previous character
Many character-level tasks depend on what came before: a word starts where a letter follows a space, a paragraph ends at two newlines in a row. Keep the previous character in a variable and update it at the end of each pass.
Your turn: copy the input to the output, but replace every run of two or more spaces with a single space. Everything else, including newlines, passes through unchanged.