fread_s读取字节数异常问题技术求助
Hey there, let's break down why you're hitting this weird feof trigger at a fixed position when reading your struct with fread_s, and how to fix it.
The Most Likely Culprit: Text Mode vs Binary Mode
Your code opens the file with "r" mode, which is text mode. For binary files (like your packed collection of small files), this is a critical mistake:
- Text mode automatically translates line endings (e.g., converting
\r\nto\non Windows), which shifts your file pointer positions unexpectedly. - Worse, in some systems, the byte
0x1A(Ctrl+Z) is treated as an end-of-file marker in text mode. If your file has this byte at the position you're trying to read,fread_swill stop immediately, triggerfeof(), and jump the file pointer past that byte (explaining the jump from 118 to 630).
Fix 1: Open the File in Binary Mode
Change your fopen_s call to use "rb" instead of "r":
fopen_s(&file, filename.c_str(), "rb");
This disables all text-mode translations and ignores 0x1A as an EOF marker, which should fix the premature feof trigger.
Additional Checks to Validate Your Workflow
Even after fixing the mode, let's make sure other parts of your code are solid:
1. Verify fseek Success
Always check the return value of fseek to ensure you're actually positioning the file pointer correctly. If fseek fails (returns -1), your read will be from the wrong position:
int seekResult = fseek(file, HEADERSIZE + i * FILEHEADERSIZE, SEEK_SET); if (seekResult != 0) { // Handle error: print errno, log, etc. perror("fseek failed"); break; }
2. Double-Check Struct Size and Packing
You already used #pragma pack(push, 1) which is correct for tight packing, but let's confirm the size matches FILEHEADERSIZE at compile time to catch any accidental changes:
// Add this line near your struct definition static_assert(sizeof(fileHeader) == FILEHEADERSIZE, "fileHeader size mismatch with FILEHEADERSIZE!");
3. Clarify feof Behavior
feof() only indicates that a previous read operation tried to read past the actual end of the file. In your case, it was triggered by the text-mode pseudo-EOF, but with binary mode, it should only activate when you truly reach the end of your collection file.
Why Was the offset Value Corrupted?
The truncated offset (showing 164 instead of 6820) is a side effect of the premature read stop. fread_s only read part of the struct before hitting the text-mode EOF, so the final __int32 field wasn't fully written. Fixing the file mode should ensure the entire struct is read correctly.
内容的提问来源于stack exchange,提问作者WizzardMaker

