C语言二进制文件食谱程序崩溃问题求助(附代码)
问题分析与修复方案
你的程序崩溃源于多个指针、文件操作和输入输出的错误,以下是具体问题和修复步骤:
核心错误点
文件指针未正确初始化:
main函数中传递给generate_file的in是未初始化的野指针,直接使用会触发崩溃。generate_file函数里调用fopen后,未将返回的文件指针赋值给in,导致后续文件操作使用的是无效值。
输入函数的问题:
gets函数已被废弃,存在缓冲区溢出风险,建议替换为fgets。scanf读取double类型的calories时,错误使用了对应int类型的%d格式符,应改为%lf。scanf读取后会在缓冲区留下换行符,导致后续fgets直接读取空行,需要手动清理。
fwrite参数错误:
你传递了指针recipe的地址(&recipe),但实际需要传递的是结构体数据的地址,也就是recipe本身(recipe是指向结构体的指针)。fwrite返回值判断错误:
直接用fwrite != 0是错误的,应该接收fwrite的返回值,判断是否等于预期写入的数量(此处为1)。内存泄漏:
使用malloc分配的recipe指针未释放,会造成内存泄漏。
修正后的代码
#include <stdio.h> #include <string.h> #include <stdlib.h> struct Recipe{ char name[30]; char difficulty[30]; double calories; }; void generate_file(){ FILE *in = fopen("recipe.bin", "wb"); if(in == NULL){ fprintf(stderr, "错误:无法打开文件\n"); exit(1); } struct Recipe *recipe = malloc(sizeof(struct Recipe)); if(recipe == NULL){ fprintf(stderr, "错误:内存分配失败\n"); fclose(in); exit(1); } printf("输入食谱名称:"); // 用fgets替代gets,同时去除换行符 fgets(recipe->name, sizeof(recipe->name), stdin); recipe->name[strcspn(recipe->name, "\n")] = '\0'; printf("输入食谱难度等级:"); fgets(recipe->difficulty, sizeof(recipe->difficulty), stdin); recipe->difficulty[strcspn(recipe->difficulty, "\n")] = '\0'; printf("输入卡路里数值:"); // 使用%lf读取double类型 scanf("%lf", &recipe->calories); // 写入结构体数据,传递指向结构体的指针 size_t write_count = fwrite(recipe, sizeof(struct Recipe), 1, in); if(write_count == 1){ printf("文件保存成功!\n"); }else{ printf("数据保存失败\n"); free(recipe); fclose(in); exit(1); } // 释放内存并关闭文件 free(recipe); fclose(in); } int main(int argc, char* argv[]){ generate_file(); return 0; }
额外说明
- 移除了
generate_file的文件指针参数,改为在函数内部直接初始化,避免野指针问题。 - 添加了
malloc失败的判断,增强程序健壮性。 - 使用
strcspn去除fgets读取到的换行符,避免字符串包含多余换行。 - 程序结束前释放了
malloc分配的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者RustyCoder
相关产品推荐
相关产品推荐

