C语言中fscanf输出正常但程序以错误码1退出的问题求助
问题排查与修复
下面是导致程序崩溃的核心问题及对应的修复方案:
1. 内存分配顺序完全错误(致命原因)
你在main函数中先执行了malloc(sizeof(info_t) * N),但此时N是未初始化的垃圾值——内存分配的大小完全随机,要么分配过小导致后续写入时缓冲区溢出(直接触发内存访问违规,错误码1),要么分配过大造成内存浪费。
正确的顺序是先获取合法的N值,再分配内存:
int main(void) { FILE* fptr = fopen("D:/ap2/lab02ex01/file.txt", "r"); // 必须检查文件是否打开成功 if (fptr == NULL) { perror("文件打开失败"); return 1; } // 先获取正确的N值 int N = read_number_of_cities(fptr); // 再根据N分配内存 info_t* cities_info = (info_t*)malloc(sizeof(info_t) * N); // 检查内存分配是否成功 if (cities_info == NULL) { perror("内存分配失败"); fclose(fptr); return 1; } allocate_info(fptr, cities_info, N); // 记得释放内存并关闭文件 free(cities_info); fclose(fptr); return 0; }
2. 循环变量名冲突导致数据覆盖/越界
allocate_info函数中,外部的int i = 0;被内部for循环的int i = 0;覆盖了——这意味着每次处理一组航班时,你都在往cities_info[0]的位置重复写入数据,要么所有航班数据都重叠,要么当需要写入cities_info[i](i>0)时触发内存越界。
修复方法:把内部循环变量名改成j,同时追踪cities_info的下标:
void allocate_info(FILE* fptr, info_t* cities_info, int N){ int i = 0; // 用于追踪cities_info的当前下标 int tmp_flights; // 加i<N限制,避免超过分配的内存范围 while(fscanf(fptr, "%d", &tmp_flights) == 1 && i < N){ printf("%d\n", tmp_flights); char tmp_departure[LENGTH], tmp_arrival[LENGTH]; int tmp_price; float tmp_duration; // 内部循环改用j作为变量 for(int j = 0; j < tmp_flights; j++){ if (i >= N) break; // 提前终止,防止越界 fscanf(fptr, "%s %s %d %f", tmp_departure, tmp_arrival, &tmp_price, &tmp_duration); strcpy(cities_info[i].departure, tmp_departure); strcpy(cities_info[i].arrival, tmp_arrival); cities_info[i].price = tmp_price; cities_info[i].duration = tmp_duration; i++; // 每写入一个条目,下标自增 } } }
3. 缺少关键错误检查
- 未检查文件打开是否成功:如果文件路径错误、权限不足,直接操作会导致未定义行为。
- 未检查
malloc返回值:内存分配失败时,后续操作cities_info会直接崩溃。 - 未限制写入范围:如果文件中的总航班数超过
N,会触发内存越界。
4. 文件指针位置的潜在问题
如果read_number_of_cities函数读取了文件开头的内容(比如第一个数字),调用allocate_info时文件指针已经移动,可能和你预期的读取逻辑冲突。可以在调用allocate_info前用rewind(fptr)重置文件指针到开头(如果需要重新读取整个文件)。
内容的提问来源于stack exchange,提问作者Azizbek Sattorov
相关产品推荐
相关产品推荐

