Added io ref
This commit is contained in:
parent
5dd0daed8a
commit
04274e14e3
|
|
@ -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)
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -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 `<stdio.h>` interface for input/output. It’s oriented around *streams* (`FILE *`) and provides both formatted and unformatted operations. C99 also introduced `<inttypes.h>` (and `<stdint.h>`) 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 <stdio.h>
|
||||
|
||||
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 <inttypes.h>
|
||||
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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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 <stdio.h>
|
||||
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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 `<termios.h>` 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 <termios.h>
|
||||
#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.
|
||||
Loading…
Reference in New Issue