如何区分fgets到达EOF与读取错误及相关技术问题咨询
fgets(): EOF, Errors, and Partial Reads Great question—this is a common point of confusion when working with C's file I/O functions, and I’ve had to work through this exact scenario before. Let’s break down each part of your question clearly:
1. Distinguishing EOF from a Read Error
When fgets() returns NULL, it can mean one of two things: you’ve hit the end of the file (EOF), or a read error occurred. To tell them apart, use the feof() and ferror() macros from <stdio.h>:
feof(stream)returns a non-zero value if the file pointer has reached EOF.ferror(stream)returns a non-zero value if a read/write error occurred on the stream.
Here’s a practical code snippet to demonstrate:
#include <stdio.h> #include <string.h> int main() { FILE *file = fopen("test.txt", "r"); if (!file) { perror("Failed to open file"); return 1; } char buffer[256]; while (fgets(buffer, sizeof(buffer), file) != NULL) { // Process the line printf("Read: %s", buffer); } // Check why fgets returned NULL if (feof(file)) { printf("\nReached end of file successfully\n"); } else if (ferror(file)) { perror("Error reading file"); // Optional: Clear the error flag to reuse the stream clearerr(file); } fclose(file); return 0; }
2. Partial Data on Read Errors
The C standard doesn’t explicitly mandate whether fgets() retains partially read data when an error occurs, but most real-world implementations do store any characters that were successfully read before the error into your str buffer. However, you shouldn’t rely on this behavior—it’s not portable across all compilers or platforms.
If an error occurs, the partial data might be incomplete or corrupted (e.g., if a disk error mid-read caused only half a line to be fetched). It’s safer to discard the buffer’s contents and handle the error appropriately (like retrying the read or aborting the operation).
3. Checking for Immediate EOF
Immediate EOF means you called fgets() on a stream that’s already at the end of the file (like an empty file). In this case:
fgets()returnsNULLfeof(stream)will be true- Your
strbuffer remains unchanged (no characters were read)
To confirm this, you can initialize the buffer to a known value before calling fgets(), then check if it’s still the same after the NULL return:
char buffer[256] = "UNTOUCHED"; if (fgets(buffer, sizeof(buffer), file) == NULL) { if (feof(file)) { if (strcmp(buffer, "UNTOUCHED") == 0) { printf("Hit EOF immediately—no data was read\n"); } else { printf("Reached EOF after reading some data\n"); } } }
This way, you can distinguish between hitting EOF after reading some content versus hitting it right away.
内容的提问来源于stack exchange,提问作者whattheels

