The Stream Abstraction
In C, we do not interact directly with files. Instead, we interact with Streams. A stream is a uniform interface for reading and writing data, regardless of whether that data is coming from a hard drive, a keyboard, or a network socket.
The Standard Library provides three streams by default:
stdin: Standard Input (Keyboard)stdout: Standard Output (Console)stderr: Standard Error (Console, unbuffered)
Working with FILE *
To work with a custom file, we use a FILE pointer. This pointer manages a buffer and tracks the current position in the file.
1. Opening a File
FILE *fp = fopen("filename.txt", "mode");
Common Modes:
"r": Read (fails if file doesn’t exist)."w": Write (overwrites existing file)."a": Append (writes to the end)."rb","wb": Binary modes (prevents OS from altering line endings).
2. Error Handling
Opening a file can fail (missing file, permission denied). Always check if the pointer is NULL.
Reading and Writing
There are three ways to move data through a stream:
| Level | Input | Output | Usage |
|---|---|---|---|
| Character | fgetc() | fputc() | Fine-grained parsing. |
| Line | fgets() | fputs() | Reading text safely. |
| Formatted | fscanf() | fprintf() | Structured data. |
| Block | fread() | fwrite() | Large binary blocks (Fastest). |
Position and Random Access
A file pointer maintains an internal “cursor.” You can move this cursor manually:
fseek(fp, offset, origin): Move the cursor.ftell(fp): Get the current cursor position.rewind(fp): Jump back to the start.
File Safety
char buffer[100]; FILE *fp = fopen("data.txt", "r"); if (fp != ) { fgets(buffer, 100, fp); fclose(fp); }
Buffered I/O
For performance, C does not write every byte to disk immediately. It stores them in a Buffer and writes them in chunks.
fflush(fp): Forces the buffer to be written to disk immediately.fclose(fp): Automatically flushes and closes the stream.
Interactive Lab
Waiting for signal...
Binary vs. Text
In Text Mode, some systems automatically convert \n to \r\n and vice-versa. In Binary Mode ("rb", "wb"), the data is moved exactly as-is, which is crucial for images, executables, and custom data structures.