C语言读取多行整数文件至数组的实现问题及优化咨询
解决将多行整数文件读取到C语言数组的问题
一、修正你现有代码的问题
你的代码存在几个关键错误,导致无法正确读取数据到数组:
- 文件指针未重置:统计完换行符后,文件指针已走到末尾,后续
fscanf无法读取内容,需要用rewind(file)将指针移回文件开头。 - 变量未定义/引用错误:代码里的
a、i未声明,M是笔误应该为myArray,且i需要从0开始计数。 - 重复调用
fscanf:循环内连续两次调用会跳过一行数据,导致丢值,只需一次调用即可。 - 行数统计不准确:若文件最后一行无换行符,统计的
N会比实际行数少1(比如示例文件4个整数仅3个换行,N会被算成3)。
修正后的完整代码:
#include <stdio.h> #include <stdlib.h> int main() { FILE *file; int N = 0; char filePath[30]; int endFile; // 必须用int类型,因为EOF是int值,char无法存储 printf("What file should be used?\n"); scanf("%s", filePath); file = fopen(filePath, "r"); if(file == NULL) { printf("This file failed to open.\n"); return 1; // 此处不能用break,直接返回退出程序 } // 正确统计行数:处理空文件和最后一行无换行的情况 endFile = getc(file); if(endFile != EOF) { N++; // 至少存在一行 for(; endFile != EOF; endFile = getc(file)) { if(endFile == '\n') { N++; } } } rewind(file); // 将文件指针重置到开头 int myArray[N]; int i = 0; int a; // 用==1判断是否成功读取整数,比!=EOF更准确(避免读取失败时的错误判断) while(fscanf(file, "%d", &a) == 1) { myArray[i] = a; printf("%d\n", a); i++; } fclose(file); // 记得关闭文件释放资源 // 此处可添加数组使用逻辑 return 0; }
二、更优的数组创建与大小确定方法
统计换行符的方法需要两次遍历文件,对于数十万行的大文件效率偏低。更高效的方案是动态扩容数组:先分配初始容量的数组,当数组存满时用realloc扩容,边读边存储,仅需遍历文件一次。
示例代码:
#include <stdio.h> #include <stdlib.h> int main() { FILE *file; char filePath[30]; int *myArray = NULL; int capacity = 100; // 初始容量,可根据实际需求调整 int count = 0; int num; printf("What file should be used?\n"); scanf("%s", filePath); file = fopen(filePath, "r"); if(file == NULL) { printf("This file failed to open.\n"); return 1; } // 初始化动态数组 myArray = (int*)malloc(capacity * sizeof(int)); if(myArray == NULL) { printf("Memory allocation failed.\n"); fclose(file); return 1; } // 读取文件并动态扩容 while(fscanf(file, "%d", &num) == 1) { if(count >= capacity) { // 每次扩容为原容量的2倍,减少扩容次数提升效率 capacity *= 2; int *temp = (int*)realloc(myArray, capacity * sizeof(int)); if(temp == NULL) { printf("Reallocation failed.\n"); free(myArray); fclose(file); return 1; } myArray = temp; } myArray[count] = num; count++; } // 可选:缩容数组到实际元素数量,节省内存 int *finalArray = (int*)realloc(myArray, count * sizeof(int)); if(finalArray != NULL) { myArray = finalArray; } // 示例:遍历输出数组内容 for(int i = 0; i < count; i++) { printf("myArray[%d] = %d\n", i, myArray[i]); } // 释放内存并关闭文件 free(myArray); fclose(file); return 0; }
这种方法的优势:
- 仅遍历文件一次,效率更高,适配大文件场景。
- 无需提前统计行数,规避了换行符统计的各种误差(如空文件、最后一行无换行)。
- 内存使用灵活,既不会因预估行数不足导致溢出,也可通过缩容避免内存浪费。
内容的提问来源于stack exchange,提问作者Justin123
相关产品推荐
相关产品推荐

