C语言二进制文件的读写

结构体的班级学生管理:加入班级学生信息文件的读写功能。采用二进制方式读写文件
分为当前目录中是否存在文件名为计算机1班的两种情况,如果不存在,就创建该文件;如果存在,就直接读入。但都要首先读入(输入写入)学生的人数,再读入(输入写入)其它信息。
下面是我写的代码
#include<stdio.h>
#include<malloc.h>
typedef struct student
{
int number;
char name[20];
union
{
unsigned int all:25;
struct
{
unsigned int year:16;
unsigned int month:4;
unsigned int day:5;
}d1;
}date;
enum sex
{
boy=1,girl=2
}var;
float score[4];
double sum;
double average;
}STU;
void main()
{
STU st[20];
STUstudents=NULL;
FILE
p;
int n,i,j;
p=fopen("d:\计算机1班.dat","rb");
if(p==NULL)
{
p=fopen("d:\计算机1班.dat","wb");
printf("输入学生数量:");
scanf("%d",&n);//先输入人数
students=(STU*)calloc(n,sizeof(STU));//据此分配内存空间
for(i=0;i<n;i++)//逐个录入学生信息
{
printf("输入第%d个同学的学号 姓名 出生日期(8位连续输入,只有个位用零补齐) 性别(男生输1,女生输2):",i+1);
scanf("%d%s%d%d",&st[i].number,st[i].name,&st[i].date,&st[i].var);
for(j=0;j<4;j++)
{
printf("输入第%d个同学第%d科成绩:",i+1,j+1);
scanf("%f",&st[i].score[j]);
}
}
fwrite(&n,4,1,p);//首先将人数写入到班级文件中,1个int,4个字节
fwrite(st,sizeof(STU),n,p);//再将所有学生的信息写入到文件中
}
else if(p!=NULL)
{
//首先读入学生人数(1个int)

    //据此动态分配学生结构体数组
    //然后从文件剩余部分读入所以学生信息
}
//最后释放动态分配的内存

}
在输入第一个同学的第一个成绩后程序就会出现错误中止,为什么呢?
还有如果文件存在,首先读入学生人数的功能是怎么实现的?然后又是怎么动态分配内存?从剩余部分继续读入学生信息的?实在不明白,麻烦在我的基础上修改和补充,但定义的结构体不要变,多谢了

你代码里在结构体里套用了共用体,
scanf("%d%s%d%d",&st[i].number,st[i].name,&st[i].date,&st[i].var);这句话中,
scanf读取数据的时候,data是结构体,%d读取结构体的数据是不对的。应该指明读取的数据。
代码修改如下:

#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef struct student
{
    int number;
    char name[20];
    union
    {
        unsigned int all:25;
        struct
        {
            unsigned int year:16;
            unsigned int month:4;
            unsigned int day:5;
        }d1;
    }date;
    enum sex
    {
        boy=1,girl=2
    }var;
    float score[4];
    double sum;
    double average;
}STU;
void main()
{
    //STU st[20]; //这个用不到
    STU* students=NULL;
    FILE *p;
    int n,i,j;

    int tnmb;
    char tname[20];
    unsigned int tall;
    int tenum;


    p=fopen("d:\\计算机1班.dat","rb");
    if(p==NULL)
    {
        p=fopen("d:\\计算机1班.dat","wb");
        printf("输入学生数量:");
        scanf("%d",&n);//先输入人数
        students=(STU*)malloc(n*sizeof(STU));//据此分配内存空间
        for(i=0;i<n;i++)//逐个录入学生信息
        {
            printf("输入第%d个同学的学号 姓名 出生日期(8位连续输入,只有个位用零补齐) 性别(男生输1,女生输2):",i+1);
            scanf("%d%s%d%d",&tnmb,tname,&tall,&tenum);
            students[i].number = tnmb;
            strcpy(students[i].name,tname);
            students[i].date.all = tall;
            if(tenum == 1)
                students[i].var = STU::boy;
            else
                students[i].var = STU::girl;
            //scanf("%d%s%d",&(students[i].number),students[i].name,&(students[i].date.all));//&(students[i].var));
            students[i].sum = 0;
            for(j=0;j<4;j++)
            {
                printf("输入第%d个同学第%d科成绩:",i+1,j+1);
                scanf("%f",&students[i].score[j]);
                students[i].sum += students[i].score[j];
            }
            students[i].average = students[i].sum/4;
        }
        fwrite(&n,4,1,p);//首先将人数写入到班级文件中,1个int,4个字节
        fwrite(students,sizeof(STU),n,p);//再将所有学生的信息写入到文件中
        fclose(p); //这里关闭文件
    }
    else if(p!=NULL)
    {
        //首先读入学生人数(1个int)    
        fread(&n,4,1,p);//读取n
        //据此动态分配学生结构体数组
        //然后从文件剩余部分读入所以学生信息
        students=(STU*)malloc(n*sizeof(STU));//据此分配内存空间
        for(i=0;i<n;i++)
        {
            fread(&students[i],sizeof(STU),1,p);
            //显示读取的内容:测试用
            printf("%d %s %d %d\n",students[i].number,students[i].name,students[i].date.all,students[i].var);
        }
        fclose(p);
    }
    //最后释放动态分配的内存
    if(students)
    {
        free(students);
        students = 0;
    }
}

用代码块格式化一下代码,不然有些转义字符看不清楚。可以根据代码给你调试看看
用你的代码在VS2010上跑了一下,没出现你说的问题啊

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632