Table of Contents

stdio.h

printf("Hello, world\n") — nearly every C tutorial starts there, which means stdio.h is usually the first header anyone touches. It provides buffered file and console I/O: FILE, stdin/stdout/stderr, printf, scanf, fopen/fclose, and a whole family of read/write functions.

#include <stdio.h>
 
// formatted output to stdout
printf("value: %d, float: %.2f, string: %s\n", 42, 3.14, "hello");
 
// formatted input from stdin
int n;
scanf("%d", &n);
 
// file I/O
FILE *f = fopen("data.txt", "r");
if (!f) { perror("fopen"); return 1; }
 
char line[256];
while (fgets(line, sizeof(line), f))
    fputs(line, stdout);
 
fclose(f);

printf format specifiers: %d/%i (int), %u (unsigned), %f/%e/%g (double), %s (string), %c (char), %p (pointer), %x/%X (hex), %zu (size_t), %% (literal %). Width and precision: %8.2f (8-wide, 2 decimal places), %-10s (left-align in 10 chars).

Common file functions:

fread(buf, size, count, f)   // read count items of size bytes each
fwrite(buf, size, count, f)  // write count items
fseek(f, offset, SEEK_SET)   // seek to absolute position
fseek(f, offset, SEEK_CUR)   // seek relative to current position
fseek(f, offset, SEEK_END)   // seek relative to end
ftell(f)                     // return current position
rewind(f)                    // seek to beginning, clear error flag

snprintf(buf, size, fmt, ...) writes formatted output to a buffer with a size limit, always null-terminates, and returns the number of characters that would have been written (excluding the null). It is the safe alternative to sprintf, which can overflow. sscanf does the inverse: parses a string using a format specifier.

I/O is buffered by default: writes accumulate in an internal buffer and are flushed to the OS on fclose, when the buffer fills, or explicitly with fflush(f). stdout is line-buffered when connected to a terminal; stderr is unbuffered, which is why error messages appear immediately even when other output is delayed.

Practice

// compile: gcc -o iodemo iodemo.c
// run: ./iodemo
// description: write a file, seek to beginning, read it back line by line
 
#include <stdio.h>
 
int main(void) {
    FILE *f = fopen("/tmp/iodemo.txt", "w+");
    if (!f) { perror("fopen"); return 1; }
 
    fprintf(f, "line one\n");
    fprintf(f, "line two\n");
    fprintf(f, "line three\n");
 
    rewind(f);
 
    char buf[64];
    while (fgets(buf, sizeof(buf), f))
        printf("read: %s", buf);
 
    fclose(f);
    return 0;
}

w+ opens for both reading and writing, creating the file if it does not exist. After writing, rewind resets the position to the start so the same file descriptor can be used to read back what was just written — no need to close and reopen.