Nearby lessons
118 of 124C - Close a File
fclose flushes buffered data to disk and releases the file handle. Learn why closing is not optional, what buffering means for your data, how to check whether the close succeeded, and how to close correctly on every exit path.
The Syntax
One argument, one return value. The return value is worth checking:
What Closing Actually Does
fflush, or when you call fclose. That is why forgetting to close can lose data that your program is certain it wrote.| Step | What happens |
|---|---|
| 1 | Any buffered writes are flushed to the operating system |
| 2 | The buffer memory is released |
| 3 | The OS file handle is released |
| 4 | The FILE structure becomes invalid |
Losing Data by Not Closing
fclose, buffered data is gone. A normal return from main flushes open streams for you, which is exactly why this bug hides so well — it only appears when something goes wrong, which is when you need the log file most.The Return Value Matters
fclose is where a full disk finally reports itself. The earlier fprintf calls succeeded because they only wrote to memory:
Never Use a Closed Pointer
After fclose, the FILE * is dangling. Setting it to NULL turns a silent disaster into a testable condition:
One fclose Per fopen
Handles are a limited resource. A loop that opens without closing exhausts them and every later fopen starts failing:
fflush vs fclose
Use fflush when you want the data on disk but still need the file open:
fflush(fp) | fclose(fp) | |
|---|---|---|
| Flushes the buffer | Yes | Yes |
| Releases the handle | No | Yes |
| File stays usable | Yes | No |
| Typical use | Live logs, progress files | Finished with the file |
Closing on Every Exit Path
An early return in the middle of a function is the classic way to leak a handle. Use a single cleanup point:
Closing Several Files
Close each one, and if a later open fails, close the ones already open before returning:
fcloseall and Program Exit
A normal exit flushes and closes open streams for you. Relying on it is still poor practice — it hides errors and delays writes:
Common Mistakes
- Forgetting
fclose— leaks a handle and risks unwritten data. - Ignoring the return value — that is where a full-disk error appears.
- Using a
FILE *after closing it — undefined behaviour; set it toNULL. - Closing twice — also undefined behaviour.
- Closing a
NULLpointer — unlikefree(NULL), this is not safe. - Opening in a loop without closing — exhausts the handle limit.
- Returning early past the
fclose— use a single cleanup label. - Assuming
fprintfreaching the disk — it reaches a buffer.
fclose immediately after the fopen and its NULL check, then fill in the work between them. You will never forget it, and every early return you add afterwards will visibly sit above a close that is already there.- fclose(fp) returns 0 on success and EOF on failure.
- Closing flushes the buffer — without it, written data can be lost.
- Every successful fopen needs exactly one fclose.
- Never use a FILE pointer after closing it; set it to NULL.
- fflush writes the buffer out without closing the file.