Reference: stdio.h
printf, scanf, fgets, files, and friends.
6 minute read
Big idea
<stdio.h> is standard input/output: printing, reading, strings-as-files, and real files. Every entry below has its signature, what it does, the gotcha that bites beginners, and a one-line example.
Writing output
printf
int printf(const char *format, ...);
Prints formatted text to the screen (stdout). Returns the number of characters printed.
- Gotcha: each
%code must match its argument's type — see Format Specifiers. Neverprintf(text)with text you didn't write; useprintf("%s", text). - Example:
printf("%s scored %d\n", name, score);
puts
int puts(const char *s);
Prints a string and a newline.
- Gotcha: it always adds
\n—puts("hi\n")prints a blank line after. - Example:
puts("Done.");
putchar
int putchar(int c);
Prints one character.
- Example:
putchar('*');
fprintf
int fprintf(FILE *stream, const char *format, ...);
printf to any stream: a file, stdout, or stderr (for error messages).
- Example:
fprintf(stderr, "bad input on line %d\n", line);
snprintf
int snprintf(char *buf, size_t size, const char *format, ...);
printf into a string, writing at most size bytes (including the '\0'). Returns the length the full text would have had.
- Gotcha: prefer it to
sprintf, which has no size limit and can overflow the buffer. If the return value is>= size, the text was cut short. - Example:
char label[16]; snprintf(label, sizeof label, "P%d", id);
Reading input
scanf
int scanf(const char *format, ...);
Reads formatted input from the keyboard (stdin). Returns how many items it filled, or EOF when the input has ended.
- Gotcha: pass addresses (
&n, but not for arrays). Check the return value.%sneeds a width (%19sforchar[20]).%cdoesn't skip whitespace;" %c"does. See Taking Input with scanf. - Example:
while (scanf("%d", &x) == 1) sum += x;
getchar
int getchar(void);
Reads one character; returns EOF at the end of input.
- Gotcha: store the result in an
int, not achar, or you can't tellEOFfrom a real character. - Example:
int c; while ((c = getchar()) != EOF) putchar(c);
fgets
char *fgets(char *buf, int size, FILE *stream);
Reads one line (up to size - 1 characters), keeping the \n. Returns NULL at end of input. The safe way to read a line. See Reading Strings.
- Gotcha: strip the newline:
buf[strcspn(buf, "\n")] = '\0';. Never use the removedgets— it can't be made safe. - Example:
char line[100]; fgets(line, sizeof line, stdin);
sscanf
int sscanf(const char *str, const char *format, ...);
scanf, but reading from a string you already have.
- Example:
int h, m; sscanf("09:45", "%d:%d", &h, &m);
Files
fopen / fclose
FILE *fopen(const char *path, const char *mode);
int fclose(FILE *stream);
Opens a file — mode "r" read, "w" write (erases it first!), "a" append, add "b" for binary. Returns NULL on failure. fclose flushes and closes it. See Opening Files.
- Gotcha: always check for
NULL; alwaysfclosewhat you open. - Example:
FILE *f = fopen("scores.txt", "r"); if (f == NULL) { perror("scores.txt"); return 1; }
fscanf / fputs / fgetc / fputc
int fscanf(FILE *stream, const char *format, ...);
int fputs(const char *s, FILE *stream);
int fgetc(FILE *stream);
int fputc(int c, FILE *stream);
The file versions of scanf, puts (without the added newline), getchar, and putchar. See Reading and Writing Files.
- Example:
while (fscanf(f, "%d", &x) == 1) count++;
fread / fwrite
size_t fread(void *dst, size_t size, size_t count, FILE *stream);
size_t fwrite(const void *src, size_t size, size_t count, FILE *stream);
Read or write raw bytes — count items of size bytes each. Return how many whole items were transferred.
- Example:
fwrite(scores, sizeof scores[0], n, f);
feof / ferror
int feof(FILE *stream);
int ferror(FILE *stream);
After a read fails, say whether it was the end of the file or an error.
- Gotcha:
while (!feof(f))loops once too many —feofis only true after a read has failed. Loop on the read's own return value instead.
perror
void perror(const char *prefix);
Prints prefix: <reason from errno> to stderr. See Error Handling.
- Example:
perror("fopen");→fopen: No such file or directory
remove / rename
int remove(const char *path);
int rename(const char *old, const char *new);
Delete or rename a file. Return 0 on success.
Constants
EOF— a negative int meaning "no more input".stdin,stdout,stderr— the three standard streams.NULL,size_t— also defined here (and in several other headers).
#include <stdio.h>
#include <string.h>
int main(void) {
char line[64];
int n = 0;
while (fgets(line, sizeof line, stdin) != NULL) {
line[strcspn(line, "\n")] = '\0';
char label[80];
snprintf(label, sizeof label, "%d: %s", ++n, line);
puts(label);
}
printf("%d lines\n", n);
return 0;
}input
first line
second, with spacesoutput
1: first line
2: second, with spaces
2 linesRun and edit it in the app.
Why store getchar()'s result in an int rather than a char?
Check yourself
Which function reads a whole line safely?
What does fopen return when it can't open the file?