From 04274e14e38509cf33564c7a961525fde53eebab Mon Sep 17 00:00:00 2001 From: Kyler Date: Thu, 27 Nov 2025 20:01:27 -0700 Subject: [PATCH] Added io ref --- docs/index.md | 1 + docs/io_ref.md | 351 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 docs/io_ref.md diff --git a/docs/index.md b/docs/index.md index d053b00..a3080bd 100644 --- a/docs/index.md +++ b/docs/index.md @@ -37,5 +37,6 @@ Next: Overview - [SE 3250 Assignment Details](./se_3250_assignment_details.html) - [Changed](./changes.html) - [Full Specification](./stack_lang_spec.html) +- [C Terminal I/O Reference](./io_ref.html) --- diff --git a/docs/io_ref.md b/docs/io_ref.md new file mode 100644 index 0000000..61ef842 --- /dev/null +++ b/docs/io_ref.md @@ -0,0 +1,351 @@ +--- +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 +2. Streams and `FILE *` +3. Opening and closing streams +4. Formatted I/O (`printf`/`scanf` families) +5. Format specifiers and `inttypes.h` +6. Character I/O +7. Line and block I/O (`fgets`, `fputs`, `fread`, `fwrite`) +8. Buffering and `setvbuf` / `fflush` +9. File positioning (`fseek`, `ftell`, `rewind`) +10. Error handling (`feof`, `ferror`, `clearerr`, `perror`) +11. Temporary files +12. Tips for safe and portable terminal I/O +13. Examples +14. POSIX terminal control (note) + +--- + +## 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 +``` + +--- + +## 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 + +--- + +If you want, I can: + +* Add a printable PDF / cheat-sheet version. +* Expand the POSIX terminal control section with a `termios` example. +* Create a one-page cheat-sheet for printing and scanning format specifiers.