关于#c语言#的问题:请问一下您之前发布的学生管理系统-如何与txt文档联系,使程序能够从文档中读取和写入数据呢

请问一下您之前发布的学生管理系统-如何与txt文档联系,使程序能够从文档中读取和写入数据呢

在运行代码前,要在程序exe相同目录下新建一个students.txt的文件,因为插入学生信息的函数里要读取历史文件信息,所以采用的是读模式打开文件,所以需要在程序同目录下新建一个students.txt的文件,代码修改如下:

#ifndef STUDENT_H
#define STUDENT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//定义学生结构体,typedef重命名,命名成student_t
typedef struct Student{
    char name[32];
    int age;
    int id;
    int score;
}student_t;
//定义班级结构体,typedef重命名,class_t
//该结构体 调用学生结构体,生成对应的结构体数组
typedef struct Class{
    student_t stu[40];//学生成员结构体
    int count;//班级人数
}class_t;
 
//原型声明
//注意:原型声明 传参位置需要加参数类型
void print_menu();
//传过来的是&my_class(班级的结构体指针) 需要用 班级的结构体指针 进行接收
 
int insert_student(class_t*);
int print_student(class_t*);
int rm_student(class_t*);
int xiugai_student(class_t*);
int PX_student(class_t*);
 
#endif


 //https://ask.csdn.net/questions/7747253?spm=1005.2025.3001.5141
void print_menu(){
    printf("-------------------------------------------------\n");
    printf("                学生管理系统                     \n");
    printf("-------------------------------------------------\n");
    printf("|   1.添加学员  2.遍历学员信息  3.修改学员信息  |\n");
    printf("|   4.删除学员  5.根据成绩降序排序  6.退出程序  |\n");
    printf("-------------------------------------------------\n");
}
 
//添加学员信息的函数
int insert_student(class_t *p_class){//主函数传输参数,接收,由于传输的是指针变量,需要定义一个同类型的指针接收
    //指针的非空检查 否则操作空指针会有段错误
    if(NULL == p_class){
        printf("入参指针为空,请检查\n");
        exit(-1);
    }
    if(40 == p_class->count)
    {
        printf("班级人数已满,无法插入\n");
        return 0;
        
    }
    
    FILE * fp = fopen("students.txt","r");
    if(fp==NULL){
        printf("文件打开失败,程序退出!\n");
        return 0;
    }
    
    int i;
    class_t ct;
    class_t * pct = &ct;
    for(i=0;i<p_class->count;i++)
    {
        
        fscanf(fp,"%s %d %d %d ",
                    pct->stu[i].name,
                    &(pct->stu[i].age),
                    &(pct->stu[i].id),
                    &(pct->stu[i].score));    
    }
    fclose(fp);
    
    fp = fopen("students.txt","w");
    if(fp==NULL){
        printf("文件打开失败,程序退出!\n");
        return 0;
    }
    //class_t ct;
    //printf("p_class->count=%d\n",p_class->count);
    printf("请输入学员信息 :姓名 年龄 学号 成绩\n");
    scanf("%s%d%d%d",
            pct->stu[p_class->count].name,
            &(pct->stu[p_class->count].age),
            &(pct->stu[p_class->count].id),
            &(pct->stu[p_class->count].score));
            
    for(i=0;i<=p_class->count;i++)
    {
        fprintf(fp,"%s %d %d %d ", 
            pct->stu[i].name,
            (pct->stu[i].age),
            (pct->stu[i].id),
            (pct->stu[i].score));
    }        
    
    fclose(fp); 
    //信息写入到指针对应的结构体的 数组 的 新的位置(count位置)
    //添加完学生后,班级人数加加
    p_class->count++;
}
 
//输出所有学员信息的函数
int print_student(class_t * p_class){
    //判断 非空检查
//    if(NULL == p_class){
//        printf("入参指针为空,请检查\n");
//        exit(-1);
//    }
//    class_t ct;
//    class_t *p_class = &ct;
    
    FILE * fp = fopen("students.txt","r");
    if(fp==NULL){
        printf("文件打开失败,程序退出!\n");
        return 0;
    }
     
//    if(0 == n)
//    {
//        printf("没有学生,无法遍历\n");
//        return 0;
//    }else{
        int i = 0;
        class_t ct;
        class_t * pct= &ct;
        //循环遍历输出,该指针指向的结构体的数组的 第i个成员
        
        char ch;
        fscanf(fp,"%c",&ch);
        if(ch==0){
            printf("没有学生,无法遍历\n");
            fclose(fp);
            return 0;
        }
        
        fp = fopen("students.txt","r");
        if(fp==NULL){
            printf("文件打开失败,程序退出!\n");
            return 0;
        }        
        while(feof(fp)==0){        
                fscanf(fp,"%s %d %d %d ",
                    pct->stu[i].name,
                    &(pct->stu[i].age),
                    &(pct->stu[i].id),
                    &(pct->stu[i].score));
                printf("%s %d %d %d \n",
                        pct->stu[i].name,
                        pct->stu[i].age,
                        pct->stu[i].id,
                        pct->stu[i].score);    
                i++;    
            }
            
            
    //fp=fopen("students.txt","r");

//            printf("%d",ch);
//        
//                
        
//    }    
    p_class->count=i;
    
    
    fclose(fp);
 
}
 
//修改学生信息
int xiugai_student(int n)
{
    //非空检查
//    if(NULL == p_class)
//    {
//        printf("修改,传入指针错误\n");
//        exit(-1);
//    }

    FILE * fp = fopen("students.txt","r");
    if(fp==NULL){
        printf("文件打开失败,程序退出!\n");
        return 0;
    }
 
    printf("请输入要修改的学生的学号>>");
    int num = 0;
    int i = 0;
    scanf("%d",&num);//接收对应的学号
    
    class_t ct;
    class_t *p_class = &ct;
    
    //循环遍历学号所对应的下标
    for(i=0;i<n;i++)
    {
        
        fscanf(fp,"%s %d %d %d ",
                    p_class->stu[i].name,
                    &(p_class->stu[i].age),
                    &(p_class->stu[i].id),
                    &(p_class->stu[i].score));    
    }
    fclose(fp);
    
    for(i=0;i<n;i++)
    {
        
        if(num == p_class->stu[i].id)
        {//如果找到,说明该学生存在
            printf("---该学生存在---\n");
            break;    
        }
        
    }    
    if(i == n )
    {
        printf("----该学生不存在----\n");
        return 0;    
    }
    printf("请输入该学生新的信息:姓名 年龄 成绩\n");
    scanf("%s%d%d",
            p_class->stu[i].name,
            &(p_class->stu[i].age),
            &(p_class->stu[i].score));
            
    fp = fopen("students.txt","w");
    if(fp==NULL){
        printf("文件打开失败,程序退出!\n");
        return 0;
    }    
    for(i=0;i<n;i++)
    {
        
        fprintf(fp,"%s %d %d %d ", 
            p_class->stu[i].name,
            (p_class->stu[i].age),
            (p_class->stu[i].id),
            (p_class->stu[i].score));
        
    }
    fclose(fp);    
                
    printf("修改成功\n");
    return 0;
}
 
 
 
 
//删除成员
int rm_student(class_t * my_class,int len)
{
    //非空检查
//    if(NULL == p_class)
//    {
//        printf("删除传入指针错误\n");
//        exit(-1);
//    }
    FILE * fp = fopen("students.txt","r");
    if(fp==NULL){
        printf("文件打开失败,程序退出!\n");
        return 0;
    }
    
    int i;
     class_t ct;
    class_t *p_class = &ct;
     for(i=0;i<len;i++)
    {
        
        fscanf(fp,"%s %d %d %d ",
                    p_class->stu[i].name,
                    &(p_class->stu[i].age),
                    &(p_class->stu[i].id),
                    &(p_class->stu[i].score));    
    }
    fclose(fp); 
    
    int num = 0;
    
    int n=0;//定义一个标识
    printf("请输入要删除的学生的学号>>");    
    scanf("%d",&num);
    //循环遍历找到该学生的学号,对应的数组的下标
    for(i=0;i<len;i++)
    {
        if(num == p_class->stu[i].id)
        {
            n=1;//标识
            printf("--该学生存在--正在删除---\n");
            break;    
        }    
    }//此时i里存的数据就是 对应学号的学生的 数组的下标
     

    
    if(n == 1)
    {
        fp = fopen("students.txt","w");
        if(fp==NULL){
            printf("文件打开失败,程序退出!\n");
            return 0;
        }
        
        //printf("i=%d\n",i);
        if(i==0&&len==1){
            my_class->count=0;
        //    printf("只有一个学生信息,清空文件!\n") ;
            //https://blog.csdn.net/QCZL_CC/article/details/122938204
            //https://www.xp.cn/b.php/75411.html
            //.truncate("students.txt",0);
//            fprintf(fp,"%s %d %d %d ", 
//                "",
//                (p_class->stu[i].age),
//                (p_class->stu[i].id),
//                (p_class->stu[i].score));
            fclose(fp);
//            fp=fopen("students.txt","r");
//             printf("feof(fp)=%d\n",feof(fp)); 
            return 0; 
        }
        //从这一位开始,由后往前,逐个赋值---覆盖
        char temp[32];
        for(;i<len-1;i++)
        {
            p_class->stu[i].age = p_class->stu[i+1].age;        
            p_class->stu[i].id = p_class->stu[i+1].id;        
            p_class->stu[i].score = p_class->stu[i+1].score;        
            strcpy(temp,p_class->stu[i].name);        
            strcpy(p_class->stu[i].name,p_class->stu[i+1].name);        
            strcpy(p_class->stu[i+1].name,temp);        
            
        }
            //    printf("i=%d,n-1=%d",i,n-1);
         for(i=0;i<len-1;i++)
        {
        //    printf("复制学生数据到文件!\n");
            fprintf(fp,"%s %d %d %d ", 
                p_class->stu[i].name,
                (p_class->stu[i].age),
                (p_class->stu[i].id),
                (p_class->stu[i].score));
            
        }
        my_class->count--;
    //    printf("i=%d\n",i);
         printf("删除成功\n");
    
        fclose(fp);
        
    }else{
        printf("----该学生不存在----\n");
        return -1;
    }
 
 
    
    
     
     
    return 0;
}
 
//排序
int PX_student(int n)
{
    int i = 0;
    int j = 0;
    //定义一个跟学生结构体 相同类型的变量,用来充当 交换数据的桶
    student_t temp;
 
     FILE * fp = fopen("students.txt","r");
    if(fp==NULL){
        printf("文件打开失败,程序退出!\n");
        return 0;
    }
    
    class_t ct;
    class_t *p_class = &ct;
    for(i=0;i<n;i++)
    {
        
        fscanf(fp,"%s %d %d %d ",
                    p_class->stu[i].name,
                    &(p_class->stu[i].age),
                    &(p_class->stu[i].id),
                    &(p_class->stu[i].score));    
    }
    fclose(fp);
    
    printf("降序排列\n");
    //冒泡排序
    //根据成绩,交换数组中的两个 学生结构体
    for(i=0;i<n;i++)
    {
        for(j=0;j<n-i-1;j++)
        {
            if(p_class->stu[j].score < p_class->stu[j+1].score)
            {
                temp = p_class->stu[j];
                p_class->stu[j] = p_class->stu[j+1];
                p_class->stu[j+1] = temp;
            }
            
        }
        
    }
    fp = fopen("students.txt","w");
    if(fp==NULL){
        printf("文件打开失败,程序退出!\n");
        return 0;
    }
     for(i=0;i<n;i++)
    {
        
        fprintf(fp,"%s %d %d %d ", 
            p_class->stu[i].name,
            (p_class->stu[i].age),
            (p_class->stu[i].id),
            (p_class->stu[i].score));
        
    }
    fclose(fp);
    printf("排序完成\n");
    return 0;
    
}


 
int main(int argc, const char *argv[])
{
    //使用结构体之前需要定义一个结构体类型的变量
 
    class_t  my_class ;//定义一个班级的结构体变量
    my_class.count = 0;//初始化班级人数
    int choose = 0;
    //循环等待客户操作
    while(1){
        //打印主菜单
        print_menu();
        printf(">>");
        scanf("%d",&choose);
        switch(choose){
            case 1://插入学生
                insert_student(&my_class);
                break;
            case 2://遍历学生
                print_student(&my_class);
                break;
            case 3://修改学生信息(没有学号)
                xiugai_student(my_class.count);
                break;
            case 4://删除学生
                rm_student(&my_class,my_class.count);
                break;
            case 5://根据成绩排序
                PX_student(my_class.count);
                break;
            case 6://退出系统
                exit(0);
                break;
            default:
                printf("输入错误,请重新输入\n");
                break;
        }
    
    }
    return 0;
}

img