Nearby lessons
117 of 124C - Open a File
fopen connects your program to a file and hands back a FILE *. Learn the full syntax, every mode string, what a file pointer really holds, and how to diagnose an open that fails.
The Syntax
Two arguments: the filename and the mode. The return value is a pointer to a FILE structure, or NULL:
The Six Basic Modes
Three letters and an optional +. The + adds the missing direction:
| Mode | Read | Write | Missing file | Existing file | Starts at |
|---|---|---|---|---|---|
"r" | Yes | No | Fails | Kept | Beginning |
"w" | No | Yes | Created | Truncated | Beginning |
"a" | No | Yes | Created | Kept | End |
"r+" | Yes | Yes | Fails | Kept | Beginning |
"w+" | Yes | Yes | Created | Truncated | Beginning |
"a+" | Yes | Yes | Created | Kept | Reads anywhere, writes at end |
Text vs Binary
Adding b requests binary mode. On Windows, text mode translates \n to a two-byte line ending on write and back on read; binary mode passes bytes through untouched:
Always Use Binary Mode for Binary Data
fwrite in text mode corrupts it on Windows. Any byte that happens to equal 0x0A gets silently expanded to two bytes on the way out, so the file you read back does not match the one you wrote. On Linux and macOS text and binary mode are identical — which is exactly why this bug survives testing and appears only on a customer's Windows machine.What a FILE Pointer Actually Is
FILE * is not the file and does not contain its data. It points to a small bookkeeping structure the library maintains — a memory buffer, your current position, the end-of-file and error flags, and the operating system's handle. Every fprintf and fgets works through it.Why an Open Fails
Several distinct causes produce the same NULL. perror tells you which one:
| Cause | Typical message |
|---|---|
File does not exist (mode "r") | No such file or directory |
| A directory in the path is missing | No such file or directory |
| No permission | Permission denied |
| The name is a directory | Is a directory |
| Too many files already open | Too many open files |
| Disk full or read-only | No space left on device |
Opening Several Files
Each open file needs its own FILE *. Close each one, and close what you opened even when a later open fails:
The Three Streams You Never Open
Three FILE * values are open before main starts. They behave like any other stream:
Filenames From the User
Take the name at run time — from a prompt or the command line — rather than hard-coding it:
Common Mistakes
- Skipping the
NULLcheck — the first read or write then crashes. - Using
"w"when you meant"a"— the existing contents are erased. - Text mode for binary data — corrupts bytes on Windows.
- Forgetting
fclose— leaks a handle and may lose buffered writes. - Reusing one
FILE *for two files — the first handle is lost and leaked. - Single backslashes in Windows paths —
"C:\temp"contains a tab character. - Reading from a file opened
"w"— the operation fails silently unless you check.
"r" for must-exist, "w" for replace, "a" for add. The + and b are refinements you add afterwards.- FILE *fp = fopen("name", "mode"); — always check the result for NULL.
- The mode string decides read/write, truncate/append, and text/binary.
- A FILE * holds the buffer, position and error flags — not the file contents.
- perror and strerror explain why an open failed.
- Every successful fopen needs a matching fclose.