Background:
Working with files in C is a fundamental skill that originated in the early implementations of the language. The C standard library (stdio.h) provides universal functions for input-output stream operations, making programs portable across operating systems.
Issue:
Beginners often make mistakes when dealing with file streams: they do not check the result of file opening, improperly manage memory for buffering, and fail to handle read or write errors. Errors in closing files can lead to resource leaks, while incorrect handling of buffers can result in data loss.
Solution:
To work correctly with files, one should always:
fopen;fread, fwrite, fscanf, fprintf functions for reading/writing;fclose.Example code:
#include <stdio.h> int main() { FILE *fp = fopen("example.txt", "w"); if (!fp) { perror("Failed to open file"); return 1; } fprintf(fp, "Hello, world!\n"); fclose(fp); fp = fopen("example.txt", "r"); if (!fp) { perror("Error opening file for reading"); return 1; } char buffer[100]; while (fgets(buffer, sizeof(buffer), fp)) { printf("%s", buffer); } fclose(fp); return 0; }
Key features:
Can a file be closed multiple times using fclose?
No, double closing of a file stream leads to undefined behavior. After fclose, the descriptor becomes invalid.
What does the fread function return if it reaches the end of the file?
fread returns the number of successfully read elements. If the end of the file is reached — the returned count may be less than expected. Always check feof and ferror for diagnostics.
Can the same file stream be used for reading and writing simultaneously?
Yes, if the file is opened in "r+" or "w+" mode, however, it is necessary to call fflush or perform another file position movement operation (fseek) before changing direction (write/read). Otherwise, the behavior is undefined.
FILE * pointer after fclose.fflush not called, stream not closed).A developer wrote data to a log file without checking the return value from fopen. After exhausting the descriptors, the file could not be opened anymore — log messages were lost.
Pros:
Cons:
In another version of the code, all return values (fopen, fwrite, fclose) were always checked. In case of error, a detailed diagnostic message was printed using perror, and the program exited correctly, releasing all resources.
Pros:
Cons: