c语言文件读取到结构体以及写入

为什么readstu这个函数不能读取学生信息,想将读取到的学生信息保存到结构体内另外问一下怎么保存信息到文件(重新打一个也可以)
使用的是c—free5编译器会出现这个问题:[Error] .c:30: error: subscripted value is neither array nor pointer


#include 
#include 
#include 
#include 
#include 
#include 
#define HH printf("%-10s%-10s%-10s%-10s%-10s\n","学号", "姓名", "语文成绩", "数学成绩", "总分")
struct student          //学生记录
{
    int       id;         //学号
    char    name[8];   //姓名
    int      chinese;   //语文成绩
    int        math;       //数学成绩
    int      sum;       //总分
}stu;
static int n=0;             //记录学生信息条数

//函数声明
void readstu(); //读取学生信息 
void menu();
void begin();
void add(struct student stu[]);
void show(struct student stu[], int i);
void showAll(struct student stu[]);
void modify(struct student stu[]);
void del(struct student stu[]);
void search(struct student stu[]);
void sort(struct student stu[]);
void menu()
{
    
    system("cls");
    printf("\n");
    printf("\t\t\t\t --------------学生成绩管理系统--------------\n");
    printf("\t\t\t\t\t\t 1 添加记录                 ︱\n");
    printf("\t\t\t\t\t\t 2 显示记录                 ︱\n");
    printf("\t\t\t\t\t\t 3 修改记录                 ︱\n");
    printf("\t\t\t\t\t\t 4 删除记录                 ︱\n");
    printf("\t\t\t\t\t\t 5 查找记录                 ︱\n");
    printf("\t\t\t\t\t\t 6 排序记录                 ︱\n");
    printf("\t\t\t\t\t\t 0 退出系统                 ︱\n");
    printf("\t\t\t\t--------------------------------------------\n");
    printf("\t\t请选择(0-6):");
}
void readstu()
{
    int i=0;
    FILE *fp;
    fp=fopen("student.txt","r");  //以读写的方式打开文件
    if(fp == NULL)
    {
        printf("文件打开失败\n");
        return;
    } 
    fscanf(fp,"%d",&n);
    for(i=0;i<n;i++)
      if(fwrite(&stu[i], sizeof(struct student),1,fp)!=1)
      printf("成功保存\n");
    fclose(fp); //关闭文件指针
    system("pause");
} 
void begin()
{
    printf("\t\t\t\t\t|======欢迎使用成绩管理系统======|\n");
    printf("\t\t\t\t\t|================================|\n");
    printf("\t\t\t\t\t|:             |\n");
    printf("\t\t\t\t\t|第六小组             |\n");
    printf("\t\t\t\t\t|成员:                 |\n");
    printf("\t\t\t\t\t|陈卓航                 |\n");
    printf("\t\t\t\t\t|滕集                 |\n");
    printf("\t\t\t\t\t|傻蛋组:                 |\n");
    printf("\t\t\t\t\t|陈庆生                 |\n");
    printf("\t\t\t\t\t|黄灵风                 |\n");
    printf("\t\t\t\t\t|                 |\n");
    printf("\t\t\t\t\t|                       |\n");
    printf("\t\t\t\t\t|                         |\n");
    printf("\t\t\t\t\t|                 |\n");
    printf("\t\t\t\t\t|================================|\n");
    printf("\t\t\t\t点击任意键登录进入系统\n");
    system("pause");
}
void add(struct student stu[])
{
    int i, id = 0; //i作为循环变量,id用来保存新学号
    char quit;  //保存是否退出的选择
    do
    {
        printf("学号:");
        scanf("%d", &id);
        for (i = 0; i < n; i++)
        {
            if (id == stu[i].id)  //假如新学号等于数组中某生的学号
            {
                printf("此学号存在!\n");
                return;
            }
        }
        stu[i].id = id;
        printf("姓名:");
        scanf("%s", &stu[i].name);
        printf("语文成绩:");
        scanf("%d", &stu[i].chinese);
        printf("数学成绩:");
        scanf("%d", &stu[i].math);
        stu[i].sum = stu[i].chinese + stu[i].math;  //计算出总成绩
        n++;  //记录条数加1
        printf("是否继续添加?(Y/N)");
        scanf("\t%c", &quit);
    } while (quit != 'N');
}

void show(struct student stu[], int i)
{
    printf("%-10d", stu[i].id);
    printf("%-10s", stu[i].name);
    printf("%-10d", stu[i].chinese);
    printf("%-10d", stu[i].math);
    printf("%-10d\n", stu[i].sum);
}

void showAll(struct student stu[])
{
    int i;
    HH;
    for (i = 0; i < n; i++)
    {
        show(stu, i);
    }
}

void modify(struct student stu[])
{
    char name[8], ch;                 //name用来保存姓名,ch用来保存是否退出的选择
    int i;
    printf("修改学生的记录。\n");
    printf("请输入学生的姓名:");
    scanf("%s", &name);
    for (i = 0; i < n; i++)
    {
        if (strcmp(name, stu[i].name) == 0)
        {
            getchar();                  //提取并丢掉回车键
            printf("找到该生的记录,如下所示:\n");
            HH;                           //显示记录的标题
            show(stu, i);                //显示数组stu中的第i条记录
            printf("是否修改?(Y/N)\n");
            scanf("%c", &ch);
            if (ch == 'Y' || ch == 'y')
            {
                getchar();   //提取并丢掉回车键
                printf("姓名:");
                scanf("%s", &stu[i].name);
                printf("语文成绩:");
                scanf("%d", &stu[i].chinese);
                printf("数学成绩:");
                scanf("%d", &stu[i].math);
                stu[i].sum = stu[i].chinese + stu[i].math;  //计算出总成绩
                printf("修改完毕。\n");
            }
            return;
        }
    }
    printf("没有找到该生的记录。\n");
}

void del(struct student stu[])
{
    int id, i;
    char ch;
    printf("删除学生的记录。\n");
    printf("请输入学号:");
    scanf("%d", &id);
    for (i = 0; i < n; i++)
    {
        if (id == stu[i].id)
        {
            getchar();
            printf("找到该生的记录,如下所示:\n");
            HH;                                //显示记录的标题
            show(stu, i);                     //显示数组stu中的第i条记录
            printf("是否删除?(Y/N)\n");
            scanf("%c", &ch);
            if (ch == 'Y' || ch == 'y')
            {
                for (; i < n; i++)
                    stu[i] = stu[i + 1];    //被删除记录后面的记录均前移一位
                n--;                          //记录总条数减1
                printf("删除成功!");
            }
            return;
        }
    }
    printf("没有找到该生的记录!\n");
}

void search(struct student stu[])
{
    char name[8];
    int i;
    printf("查找学生的记录。\n");
    printf("请输入学生的姓名:");
    scanf("%s", &name);
    for (i = 0; i < n; i++)
    {
        if (strcmp(name, stu[i].name) == 0)
        {
            printf("找到该生的记录,如下所示:\n");
            HH;            //显示记录的标题
            show(stu, i); //显示数组stu中的第i条记录
            return;
        }
    }
    printf("没有找到该生的记录。\n");
}

void sort(struct student stu[])
{
    int i, j;
    struct student t;
    printf("按总成绩进行排序,");
    for (i = 0; i < n - 1; i++)           //双层循环实现总分的比较与排序
    {
        for (j = i + 1; j < n; j++)
        {
            if (stu[i].sum < stu[j].sum)
            {
                t = stu[i];
                stu[i] = stu[j];
                stu[j] = t;
            }
        }
    }
    printf("排序结果如下:\n");
    showAll(stu);                          //显示排序后的所有记录
}

//主函数 
int main()
{
    begin();
    struct student stu[50];
    int select,quit=0;

    while(1)
    {
            menu();
        scanf("%d",&select);
        switch(select)
        {
            case 1:
            add(stu);
            break;
            case 2:
            showAll(stu);
            break;
            case 3:
            modify(stu);
            break;
            case 4:
            del(stu);
            break;
            case 5:
            search(stu);
            break;
            case 6:
            sort(stu);
            break;
            case 0:
            quit=1;
            break;
            default:
            printf("请输入0~6之间的数字\n");
            break;
        }
        if(quit==1)
        break;
        printf("按任意键返回主菜单!\n");
        getchar();
        getchar();
    }
    printf("程序结束!\n");
    return 0; 
}

你贴出你的txt才好调试啊。

void add(struct student stu[]);
这种老的写法,一些编译器不认识,可以写
void add(student *stu);
代替

readstu()中,应该使用fread()来读取文件中的学生信息并保存到结构体中,代码应该修改为:

void readstu() {
    int i = 0;
    FILE* fp;
    fp = fopen("student.txt", "r");  // 以只读的方式打开文件
    if (fp == NULL) {
        printf("文件打开失败\n");
        return;
    }
    fscanf(fp, "%d", &n);
    for (i = 0; i < n; i++) {
        fread(&stu[i], sizeof(struct student), 1, fp); // 读取学生信息
    }
    fclose(fp); // 关闭文件指针
    printf("成功读取%d条学生信息!\n", n);
    system("pause");
}

学生信息保存到文件:

void save(struct student stu[]) {
    FILE* fp;
    fp = fopen("student.txt", "w"); // 以只写的方式打开文件
    if (fp == NULL) {
        printf("文件打开失败\n");
        return;
    }
    fprintf(fp, "%d\n", n); // 先将学生记录条数写入文件
    for (int i = 0; i < n; i++) {
        fprintf(fp, "%d %s %d %d %d\n", stu[i].id, stu[i].name, stu[i].chinese, stu[i].math, stu[i].sum); // 将每条学生记录写入文件
    }
    fclose(fp); // 关闭文件指针
    printf("成功保存%d条学生信息!\n", n);
    system("pause");
}