如何用C语言编写代码读取文件整数?新手遇内存访问错误求助
Hey there! That memory access error is a classic pitfall for new C programmers—let's break down the most likely causes and fix your code step by step.
Common Reasons for the Error
1. You're Using a NULL File Pointer
If your fopen() call fails (e.g., the file doesn't exist, you have wrong permissions, or the path is incorrect), it returns NULL. Trying to read from a NULL pointer will immediately trigger that EXC_BAD_ACCESS error.
2. Array Index Out of Bounds
If your array isn't large enough to hold all the integers you're reading, or your loop runs too many times, you'll write to memory that doesn't belong to your array. C doesn't do automatic bounds checking, so this leads to illegal memory access.
3. Not Checking if fscanf() Actually Reads Data
If your file has fewer integers than you expect, or the data isn't formatted correctly, fscanf() will fail—but if you don't check its return value, your loop will keep running and try to write to invalid array indices.
A Fixed Example Code
Here's a robust version of your program that addresses all these issues. I'll assume you're working with 12 months of data (adjust MONTHS if you have more/less):
#include <stdio.h> #include <stdlib.h> #define MONTHS 12 // Define the number of months upfront int main() { int water_supply[MONTHS]; // Array to hold monthly data FILE *fp = fopen("water_data.txt", "r"); // Open the data file // First, check if the file opened successfully if (fp == NULL) { perror("Error opening file"); // Tells you exactly why it failed return EXIT_FAILURE; } int months_read = 0; // Read data, stopping when we hit the end of the array or file for (; months_read < MONTHS; months_read++) { // Check if fscanf successfully read an integer if (fscanf(fp, "%d", &water_supply[months_read]) != 1) { printf("Warning: Stopped early—only read %d months of data\n", months_read); break; } } // Print out the data to verify printf("Successfully read monthly water supply data:\n"); for (int i = 0; i < months_read; i++) { printf("Month %d: %d million gallons\n", i + 1, water_supply[i]); } fclose(fp); // Don't forget to close the file! return EXIT_SUCCESS; }
Key Fixes Explained
- File Pointer Check: The
if (fp == NULL)block catches cases where the file can't be opened, so you don't try to read from invalid memory. - Array Bounds Control: The loop stops when
months_readhitsMONTHS, so you never write past the end of the array. fscanf()Return Value Check:fscanf()returns the number of items it successfully read. We check if it's 1 (meaning we got an integer) to avoid invalid writes.
Quick Tips for Your Workflow
- Double-check that your data file is in the same directory as your compiled program, or use the full file path (e.g.,
/Users/you/Documents/water_data.txton macOS). - Count how many integers are in your data file and make sure
MONTHSmatches that number (or make the array dynamically sized withmalloc()if you don't know the count upfront). - Always clean up: call
fclose()on your file pointer when you're done with it—good practice prevents resource leaks.
内容的提问来源于stack exchange,提问作者John McKinnon

