C CLP study materials
C CLP study resources

C CLP: Standard Library Usage and File I/O

C CLP · Work through your exam, one topic at a time.

All guide sections

Standard Library Usage and File I/O

This domain tests practical use of <stdio.h> plus the conversion and utility functions in <stdlib.h>: correct mode strings, correct return-value checking, and the distinction between EOF, a read error, and a valid byte.

File streams

  • FILE *fopen(const char *path, const char *mode) returns NULL on failure - always check. Modes: "r", "w" (truncates), "a" (appends), with + for update and b for binary; on POSIX systems text and binary modes behave identically, on Windows they do not.
  • fclose flushes and releases the stream; fflush pushes buffered output. stdin, stdout, and stderr are pre-opened, and stderr is unbuffered by default.
  • fread/fwrite return the number of complete items transferred, not the number of bytes.
  • fgetc/getchar return int so that EOF (negative, usually -1) is distinguishable from every valid byte. fgets(buf, n, fp) reads at most n-1 characters, keeps any newline, and NUL-terminates; fputs does not add a newline.
  • feof becomes true only after a read attempts to pass the end; ferror reports an I/O error. perror and strerror translate errno into a message.

Conversions and utilities

  • atoi cannot report failure; strtol(str, &end, base) sets end to the first unconverted character and errno to ERANGE on overflow. strtod is the floating-point analogue.
  • qsort(base, n, size, cmp) needs a comparator returning negative, zero, or positive values; bsearch requires the same ordering.
  • exit(status) runs atexit handlers and flushes streams; abort() does not.

Worked example

char buf[128];
FILE *fp = fopen("data.txt", "r");
if (fp == NULL) { perror("data.txt"); return 1; }
while (fgets(buf, sizeof buf, fp) != NULL) {
    fputs(buf, stdout);
}
if (ferror(fp)) perror("read");
fclose(fp);

fgets is used as the loop condition because it fails at end of file, at an error, or on a short read. Writing while (!feof(fp)) instead tests the flag before the failing read, so the final line is processed twice.

Traps

  • while (!feof(fp)) - the classic duplicated last record.
  • char c = getchar(); truncates EOF.
  • scanf("%d", x) instead of scanf("%d", &x), or ignoring scanf's return value, which counts converted items.
  • Opening with "w" when "a" was meant, destroying the existing file.
  • Mixing scanf and fgets on the same stream, leaving an unconsumed newline.
  • Forgetting fclose, so buffered output never reaches the file.