读取文件长度异常问题求助:附测试文件及C语言读取代码
Hey there, let's break down why your file length calculation and reading might be behaving unexpectedly. Here are the key issues to look at, plus fixes to get your code working reliably:
1. Text Mode vs Binary Mode Discrepancy
On Windows systems, opening a file with "r" uses text mode, which automatically translates line endings (converting \r\n to \n). When you use fseek(f, 0, SEEK_END) followed by ftell(f) in text mode, the value you get is the number of characters (after newline conversion), not the actual number of bytes in the file. This means your size variable will be smaller than the true file size if the file contains Windows-style line endings, leading to incomplete reads or incorrect length reports.
Fix: Open the file in binary mode using "rb" instead:
FILE *f = fopen(path, "rb");
2. Missing Error Checks for ftell
ftell can fail (e.g., if the file is larger than the maximum value of long, or if fseek didn't work properly), returning -1L. Using this invalid value to allocate memory will cause undefined behavior. Always validate the result:
fseek(f, 0, SEEK_END); long size = ftell(f); if (size == -1L) { fclose(f); fprintf(stderr, "Failed to get file size with ftell\n"); return EXIT_FAILURE; }
3. Not Verifying fread Success
fread returns the number of elements it successfully read. If this number doesn't match your expected size, it means the read operation didn't complete (e.g., file corruption, disk error, or the file was modified mid-read). Add a check to catch this:
size_t bytes_read = fread(text, sizeof(char), size, f); if (bytes_read != size) { fprintf(stderr, "Warning: Only read %zu of %ld bytes\n", bytes_read, size); // Optionally handle the error, e.g., truncate the string to the actual read length text[bytes_read] = '\0'; }
4. Memory Leak & Malloc Check
Your original code didn't free the allocated text pointer, which will cause a memory leak. Also, malloc can fail (return NULL), so you should add a check for that too.
Modified Working Code
Here's your code with all these fixes applied:
#include <stdio.h> #include <stdlib.h> int main() { // read file to text char *path = "D:/tst.txt"; FILE *f = fopen(path, "rb"); // Use binary mode if(!f) { fprintf(stderr, "Failed to open file\n"); return EXIT_FAILURE; } fseek(f, 0, SEEK_END); long size = ftell(f); if (size == -1L) { fclose(f); fprintf(stderr, "ftell failed\n"); return EXIT_FAILURE; } fseek(f, 0, SEEK_SET); char *text = malloc((size + 1) * sizeof(char)); if (!text) { // Check malloc success fclose(f); fprintf(stderr, "malloc failed\n"); return EXIT_FAILURE; } text[size] = '\0'; size_t bytes_read = fread(text, sizeof(char), size, f); if (bytes_read != size) { fprintf(stderr, "Incomplete read: %zu bytes read out of %ld\n", bytes_read, size); text[bytes_read] = '\0'; } fclose(f); // Test result printf("Size of text: %ld\n", size); printf("Text content: %s\n", text); free(text); // Free allocated memory return EXIT_SUCCESS; }
内容的提问来源于stack exchange,提问作者1 1

