--- Title: C Terminal I/O Reference Prev: Next: --- *This was generated by ChatGPT as a reference to assist in development.* # C99 Terminal I/O Reference A concise, practical reference for terminal (stdin/stdout/stderr) and file I/O in **C99**. Includes common functions, behavior notes, examples, and safe-usage tips. --- ## Table of contents 1. [Overview](#1-overview) 2. [Streams and `FILE *`](#2-streams-and-file) 3. [Opening and closing streams](#3-opening-and-closing-streams) 4. [Formatted I/O (`printf`/`scanf` families)](#4-formatted-io-printfscanf-families) 5. [Format specifiers and `inttypes.h`](#6-character-io) 6. [Character I/O](#6-character-io) 7. [Line and block I/O (`fgets`, `fputs`, `fread`, `fwrite`)](#7-line-and-block-io) 8. [Buffering and `setvbuf` / `fflush`](#8-buffering-and-setvbuf-fflush) 9. [File positioning (`fseek`, `ftell`, `rewind`)](#9-file-positioning) 10. [Error handling (`feof`, `ferror`, `clearerr`, `perror`)](#10-error-handling) 11. [Temporary files](#11-temporary-files) 12. [Tips for safe and portable terminal I/O](#12-tips-for-safe-and-portable-terminal-io) 13. [Examples](#13-examples) 14. [POSIX terminal control (note)](#14-posix-terminal-control-note) 15. [Quick reference: common functions](#15-quick-reference-common-functions) --- ## 1. Overview Standard C99 defines the `` interface for input/output. It’s oriented around *streams* (`FILE *`) and provides both formatted and unformatted operations. C99 also introduced `` (and ``) for precise integer types and format macros. The standard I/O streams preopened by the implementation are: * `stdin` — standard input (usually the keyboard/pipe) * `stdout` — standard output (usually the terminal/pipe) * `stderr` — standard error (usually the terminal, unbuffered) `stdout` is usually line-buffered when connected to a terminal and fully buffered when redirected to a file. --- ## 2. Streams and `FILE *` `FILE` is an opaque type representing an I/O stream. Use pointers to `FILE` returned by `fopen`, or the standard `stdin`/`stdout`/`stderr`. Common operations: read/write, reposition, flush, close, and check errors. --- ## 3. Opening and closing streams ```c #include FILE *fopen(const char *pathname, const char *mode); int fclose(FILE *stream); ``` `mode` examples: * `"r"` — read (file must exist) * `"w"` — write (truncate/create) * `"a"` — append (create if needed) * `"r+"` — read/update * `"w+"` — read/update (truncate/create) * Add `b` for binary: `"rb"`, `"wb"` (on POSIX `b` is ignored but required for portability to Windows) Always check for `NULL` from `fopen` and nonzero return from `fclose`. --- ## 4. Formatted I/O (`printf`/`scanf` families) **Output (formatted)** ```c int printf(const char *format, ...); int fprintf(FILE *stream, const char *format, ...); int snprintf(char *str, size_t size, const char *format, ...); int vprintf(const char *format, va_list ap); ``` Return value: number of characters written (excluding terminating `\0` for `snprintf`) or a negative value on error. **Input (formatted)** ```c int scanf(const char *format, ...); int fscanf(FILE *stream, const char *format, ...); int sscanf(const char *str, const char *format, ...); ``` `scanf`-style functions parse input according to `format`. They are error-prone for untrusted input — prefer `fgets` + `sscanf` or manual parsing. **Important:** Always limit field widths for `%s` and others when using `scanf` to avoid buffer overflow: `%99s` for a 100-byte buffer. --- ## 5. Format specifiers and `inttypes.h` Common specifiers: * `%d` — `int` * `%i` — `int` (auto-detects base) * `%u` — `unsigned int` * `%ld` — `long int` * `%lld` — `long long int` * `%zu` — `size_t` * `%f` — `float` (promoted to `double` in `printf`/`scanf` variadic calls — use `%f` with `double` in `printf`; `scanf` expects pointer to `float` for `%f`) * `%lf` — `double` for `scanf` (in `printf` `%f` and `%lf` are equivalent) * `%Lf` — `long double` * `%c` — `char` (or `int` in `printf`), for `scanf` expects `char *` * `%s` — NUL-terminated string * `%p` — pointer * `%n` — write number of characters printed so far into `int *` For fixed-width integer types introduced in C99, use `inttypes.h` macros ```c #include int32_t i32; printf("%" PRId32 "\n", i32); ``` Common macros: `PRId32`, `PRIu64`, `PRIxPTR`, etc. --- ## 6. Character I/O ```c int getchar(void); int putchar(int ch); int ungetc(int ch, FILE *stream); int fgetc(FILE *stream); int fputc(int ch, FILE *stream); ``` * `getchar()` is equivalent to `fgetc(stdin)`. * Return values for `fgetc`/`getchar`: next character as an unsigned char cast to `int`, or `EOF` on end-of-file or error. * `ungetc` pushes a character back onto the stream (one character is guaranteed). --- ## 7. Line and block I/O **Line-based** ```c char *fgets(char *s, int size, FILE *stream); int fputs(const char *s, FILE *stream); ``` * `fgets` reads up to `size-1` characters or until newline; the resulting string includes the newline if present and is NUL-terminated. Returns `NULL` on EOF or error. * Use `fgets` to safely read lines from `stdin` (avoid `gets`). **Block-based (binary)** ```c size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); ``` * Returns number of elements read/written; check against `nmemb` to detect short reads/writes. --- ## 8. Buffering and `setvbuf` / `fflush` Buffering modes: * Fully buffered — data collected until buffer fills (default for files). * Line buffered — buffer flushed on newline (default for interactive `stdout`). * Unbuffered — no buffering (default for `stderr`). Control buffering: ```c int setvbuf(FILE *stream, char *buf, int mode, size_t size); int setbuf(FILE *stream, char *buf); // simpler wrapper int fflush(FILE *stream); // flush output buffer ``` `mode` constants: `_IOFBF` (full), `_IOLBF` (line), `_IONBF` (none). Call `fflush(stdout)` to ensure output is written (useful before `scanf` or when using `fork`). --- ## 9. File positioning ```c int fseek(FILE *stream, long offset, int whence); long ftell(FILE *stream); void rewind(FILE *stream); ``` * `whence`: `SEEK_SET`, `SEEK_CUR`, `SEEK_END`. * For binary files larger than `LONG_MAX`, POSIX defines `fseeko`/`ftello` with `off_t` (not in C99 standard). --- ## 10. Error handling ```c int feof(FILE *stream); int ferror(FILE *stream); void clearerr(FILE *stream); ``` * `ferror` indicates if an error occurred on the stream. * `perror(const char *s)` prints a human-readable error message based on `errno`. Example pattern: ```c if (ferror(fp)) { perror("file read"); } ``` --- ## 11. Temporary files ```c FILE *tmpfile(void); // create and open a temporary binary file (removed on close) char *tmpnam(char *s); // generate a filename ``` `tmpnam` is unsafe for race conditions; prefer `tmpfile` or platform-specific secure alternatives. --- ## 12. Tips for safe and portable terminal I/O * Prefer `fgets` + `sscanf` (or manual parsing) over `scanf` to avoid buffer overflows and ambiguous input parsing. * When printing into buffers, use `snprintf` to avoid overflows and to detect truncation (it returns the number of characters that would have been written). * Validate `fread`/`fwrite` return values. * Check `fopen` for `NULL` and call `perror`/inspect `errno` on failure. * Use `fflush(stdout)` if mixing output with `fork()` or before expecting input on interactive programs. * Use `setvbuf` if your program has special performance needs. * For cross-platform portability, include `b` in mode strings for binary files (Windows requires it). * Use `inttypes.h` macros for printing fixed-width integers. --- ## 13. Examples ### Read lines from stdin safely ```c #include #include int main(void) { char buf[256]; while (fgets(buf, sizeof buf, stdin)) { // strip newline size_t len = strlen(buf); if (len && buf[len - 1] == '\n') buf[len - 1] = '\0'; printf("line: '%s'\n", buf); } return 0; } ``` ### Read integers robustly using `fgets` + `sscanf` ```c #include int main(void) { char line[128]; long value; while (fgets(line, sizeof line, stdin)) { if (sscanf(line, "%ld", &value) == 1) { printf("got: %ld\n", value); } else { fprintf(stderr, "invalid input: %s", line); } } } ``` ### Write/read binary struct to file ```c #include #include struct pair { int a; double b; }; int main(void) { struct pair p = {42, 3.14159}; FILE *f = fopen("data.bin", "wb"); if (!f) { perror("fopen"); return 1; } if (fwrite(&p, sizeof p, 1, f) != 1) { perror("fwrite"); } fclose(f); f = fopen("data.bin", "rb"); struct pair q; if (!f) { perror("fopen"); return 1; } if (fread(&q, sizeof q, 1, f) != 1) { perror("fread"); } fclose(f); printf("read: %d %f\n", q.a, q.b); } ``` --- ## 14. POSIX terminal control (note) C99 does **not** standardize low-level terminal control (raw mode, disabling echo, key-by-key input). On POSIX systems you can use `` and `tcgetattr`/`tcsetattr`. On Windows you use console APIs (`GetConsoleMode` / `SetConsoleMode`). These are outside the C standard and require conditional compilation and platform-specific code. Example POSIX-only header include: ```c #ifdef __unix__ #include #endif ``` --- ## 15. Quick reference: common functions * `fopen`, `fclose` — open/close file * `fread`, `fwrite` — block I/O * `fgets`, `fputs` — line I/O * `printf`, `fprintf`, `snprintf` — formatted output * `scanf`, `fscanf`, `sscanf` — formatted input * `fgetc`, `fputc`, `getchar`, `putchar` — character I/O * `fflush`, `setvbuf` — flushing and buffering * `fseek`, `ftell`, `rewind` — positioning * `feof`, `ferror`, `clearerr`, `perror` — error handling * `tmpfile`, `tmpnam` — temporary files [Back to Top](#c99-terminal-io-reference)