zoukankan      html  css  js  c++  java
  • C语言文件实现学生成绩管理

    C语言实现学生成绩管理

    •    项目简介                          

                    用C语言的链表及文件操作实现学生成绩的管理,实现主要的添加、修改、删除、查询的主要功能,并在程序关闭时将数据存储在二进制的文件中并加密。下一次打开程序,先解密二进制文件,然后将数据读入内存,再允许用户的操作。

    •    程序简示图

               

               

    •      功能介绍

                1. 加密数据:

                   程序结束时,现将生成的链表,写入二进制的临时文Temp.dat,再运用加密函数,将Temp.dat加密到文件Data.dat(就相当于数据库),并删除文件Temp.dat。程序开始运行时,先获取文件Data.dat的文件,并判断是数据,如果前两者之一的条件不满足则进入上图所示的添加数据并生成链表。如果获取到文件并且有数据,则解密到临时文件并将其读入到内存并生成链表。

                 2.加密算法:

                  加密算法采用简单XOR算法,也就是异或运算。利用了一个数与其自身相异或的到0,而与0异或也得到其本身。

               

    1  如b为原文,a为加密后的密文,c代表密码,则
    2 
    3 加密:
    4     a=b^c;
    5 
    6 解密
    7     a^c=>b^c^c=>b

                   具体的该程序的加密,因为是对二进制文件加密,采用的是先将数据写入临时文件Temp.dat,再将其数据以一个一个字节读出加密,然后依次读入到文件Data.dat完成加密。

                

     1 #define KEY 0x85
     2 
     3 void secretFile(char *srcfile,char *dstfile){
     4          FILE *fp1,*fp2;
     5 
     6       if((fp1=fopen(srcfile,"rb"))==NULL){  //获取被加密文件指针
     7          return ;
     8       }
     9 
    10       if((fp2=fopen(dstfile,"wb"))==NULL){ //获取加密文件指针
    11         return;
    12       }
    13 
    14       fseek(fp1,0,SEEK_END);
    15       int length=ftell(fp1);   //获取文件的长度
    16 
    17       fseek(fp1,0,SEEK_SET);
    18 
    19       char *p=(char *)malloc(sizeof(char)*length);
    20       fread(p,sizeof(char),length,fp1);//将文件数据读入p所指内存空间
    21 
    22       for(int i=0;i<length;i++){
    23          p[i]^=KEY;
    24       }                                          //异或加密
    25 
    26       fwrite(p,sizeof(char),length,fp2);//将加密后的数据读入目标文件
    27 
    28           fclose(fp1);
    29       fclose(fp2);    
    30 }
               调用加密函数
     1 void jiemi(){        //解密
     2     FILE *fp;
     3     if((fp=fopen("Temp.dat","wb"))==NULL){
     4        return;
     5     }                              //生成临时文件
     6     fclose(fp);
     7     secretFile("Data.dat","Temp.dat");  //解密到临时文件
     8 }
     9 
    10 
    11 void jiami(){     //加密
    12     FILE *fp;
    13     if((fp=fopen("Data.dat","wb"))==NULL){
    14        return;
    15     }
    16     fclose(fp);
    17         secretFile("Temp.dat","Data.dat"); //加密到目标文件
    18     remove("Temp.dat");             //删除临时文件
    19 }

        执行后的二进制文件用WinHEX查看:

        加密前的文件:

       

       加密后的文件:

      在具体的代码为了安全,生成加密文件Data.dat会删除临时文件Temp.dat,更安全的应该是由用户输入KEY值加密,然后输入KEY解密,就相当于文件的密码。这里定义宏写入了KEY的值。

        3.写入、读取文件

        读取Temp.dat的文件生成链表,返回头指针

    1 struct student *readData(){
     2    jiemi();      //调用解密,生成解密后的文件Temp.dat
     3 
     4    struct student *head,*q,*p;
     5    head=q=NULL; 
     6    int i=0;
     7    FILE *fp;
     8        if((fp=fopen("Temp.dat","rb"))==NULL){
     9        printf("打开文件 Temp.dat 失败\n");
    10     }
    11                            //获取文件指针
    12
    13    fseek(fp,0,SEEK_END);
    14    int length=ftell(fp)/(sizeof(struct student));
    15                           //获取文件长度,确定链表的长度
    16    fseek(fp,0,SEEK_SET);
    17                         
    18     while(i<length){
    19         
    20         p=(struct student*)malloc(sizeof(struct student));
    21 
    22                 fread(p,sizeof(struct student),1,fp); //读数据到p
    23 
    24                 if(head==NULL){           //生成头结点
    25            head=q=p;
    26         }else{                       
    27            q->next=p;               //在尾节点添加数据
    28            q=p;
    29         }  
    30         i++;
    31     }
    32     q->next=NULL;          //尾节点置为空
    33     fclose(fp);
    34     return head;
    35     
    36 }

         将内存中的链表存储到文件

     1 void storeData(struct student *head){
     2     struct student *q;
     3     FILE *fp;
     4     if((fp=fopen("Temp.dat","wb"))==NULL){
     5        printf("打开文件 Temp.dat 失败\n");
     6            return;
     7     }                                //获取文件指针
     8     for(q=head;q!=NULL;q=q->next){
     9         
    10         fwrite(q,sizeof(struct student),1,fp); //将链表上的节点依次写入文件
    11     }
    12     fclose(fp);
    13         printf("存储数据成功");
    14 }

    具体代码:

        头文件head.h:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #include<malloc.h>
     5 
     6 #define KEY 0x85   //定义加密字符串
     7 
     8 struct student{
     9    char id[10];        //学号
    10    char name[20]; //姓名
    11    int math;          //数学成绩
    12    int english;       //英语成绩
    13    struct student *next;
    14 };             //学生结构体
    15 
    16 void secretFile(char *srcfile,char *dstfile);//加密函数
    17 void jiemi(); //解密
    18 void jiami(); //加密
    19 bool isData(struct student *head,char tmp[]);//是否存在该节点
    20 struct student* creatLink();//生成链表
    21 struct student* findLink(struct student *head,char id[]);//查找节点
    22 void infoDisplay(struct student *head);//查看所有节点信息
    23 void chaxun(struct student *head);//查询学生信息
    24 struct student* tianjia(struct student *head);//添加学生
    25 struct student* deleteLink(struct student *head);//删除学生
    26 struct student* xiugai(struct student *head);//修改学生信息
    27 bool isFile(char filename[]);//判断是否存在文件
    28 void storeData(struct student *head);//存储数据到文件
    29 struct student *readData();//读入数据生成链表
    33 void freeLink(struct sutdent *head);//释放链表

    主函数main.cpp:

     1 #include"head.h"
     2 
     3 void menu(){
     4     struct student *head=NULL;
     5     system("cls");
     6     if(false==isFile("Data.dat")){
     7        printf("第一次进入:请先添加数据:\n");
     8        head=creatLink();
     9 
    10     } else{
    11        head=readData();
    12     
    13     }
    14     int iSelect=1;
    15     while(iSelect!=6){
    16          system("cls");
    17          printf("请输入选项:\n");
    18          printf("1.查询成绩   2.添加成绩  3.删除成绩  4.修改成绩  5.数据一览 6.退出\n");
    19          scanf("%d",&iSelect);
    20          switch(iSelect){
    21                 case 1:chaxun(head);break;
    22                 case 3:head=deleteLink(head);break;
    23                 case 2:head=tianjia(head);break;
    24                 case 4:head=xiugai(head);break;
    25                 case 5:infoDisplay(head);break;
    26                 case 6:storeData(head);freeLink(head);jiami();system("pause");break;
    27                 default:printf("\n输入错误请重新输入:");system("pause");break;
    28          }
    29     }
    30 }
    31 
    32 
    33 int main(){
    34    menu();
    35    return 0;
    36 }

    具体函数function.cpp:

      1 #include"head.h"
      2 
      3 void freeLink(struct student *head){
      4    struct student *p,*q;
      5    p=head;
      6    while(p!=NULL){
      7        q=p;
      8        p=p->next;
      9        free(q);
     10    }
     11 }
     12 
     13 
     14 void secretFile(char *srcfile,char *dstfile){
     15       FILE *fp1,*fp2;
     16       if((fp1=fopen(srcfile,"rb"))==NULL){
     17          return ;
     18       }
     19       if((fp2=fopen(dstfile,"wb"))==NULL){
     20         return;
     21       }
     22       fseek(fp1,0,SEEK_END);
     23       int length=ftell(fp1);
     24       fseek(fp1,0,SEEK_SET);
     25       char *p=(char *)malloc(sizeof(char)*length);
     26       fread(p,sizeof(char),length,fp1);
     27       for(int i=0;i<length;i++){
     28          p[i]^=KEY;
     29       }
     30       fwrite(p,sizeof(char),length,fp2);
     31       fclose(fp1);
     32       fclose(fp2);    
     33 }
     34 
     35 
     36 void jiemi(){
     37     FILE *fp;
     38     if((fp=fopen("Temp.dat","wb"))==NULL){
     39        return;
     40     }
     41     fclose(fp);
     42     secretFile("Data.dat","Temp.dat");
     43 }
     44 
     45 
     46 void jiami(){
     47     FILE *fp;
     48     if((fp=fopen("Data.dat","wb"))==NULL){
     49        return;
     50     }
     51     fclose(fp);
     52     secretFile("Temp.dat","Data.dat");
     53     remove("Temp.dat");
     54 }
     55 
     56 
     57 bool isData(struct student *head,char tmp[]){
     58     struct student *q;
     59     printf("flag\n");
     60     for(q=head;q!=NULL;q=q->next){
     61         if(strcmp(tmp,q->id)==0){
     62            return true;
     63         }
     64     }
     65 
     66     return false;
     67 }
     68 
     69 //创建链表 
     70 struct student* creatLink(){
     71       struct student *head,*q,*p;
     72       head=q=NULL;
     73       char id[10];
     74       int i=0;
     75 
     76       head=q=NULL;
     77       while(1){
     78           printf("(#结束输入)\n请输入学号:");
     79           scanf("%s",id);
     80           if(strcmp("#",id)==0){
     81               break;
     82           }
     83           p=(struct student*)malloc(sizeof(struct student));
     84           strcpy(p->id,id);
     85 
     86           fflush(stdin);
     87           printf("请输入姓名:");
     88           scanf("%s",p->name);
     89 
     90           fflush(stdin);
     91           printf("请输入数学成绩:");
     92           scanf("%d",&(p->math));
     93 
     94           fflush(stdin);
     95           printf("请输入英语成绩:");
     96           scanf("%d",&(p->english));
     97           if(head==NULL){
     98              head=q=p;
     99              q->next=NULL;
    100           }else{
    101               if(isData(head,p->id)==true){
    102                  printf("已经存在该学生,该次数据无效\n");
    103               }
    104               else{
    105                  q->next=p;
    106                  q=p;
    107                  q->next=NULL;
    108               }           
    109           }
    110       }
    111       q->next=NULL;
    112       return head;
    113 }
    114 
    115 
    116 
    117 
    118 
    119 
    120 struct student* findLink(struct student *head,char id[]){
    121    struct student *p;
    122    for(p=head;p!=NULL;p=p->next){
    123       if(strcmp(id,p->id)==0)break;
    124    }
    125    if(p!=NULL){
    126       return p;
    127    }
    128    return NULL;
    129 }
    130 
    131 
    132 
    133 
    134 void infoDisplay(struct student *head){
    135    struct student *p;
    136    system("cls");
    137    printf("学号\t姓名\t英语\t数学\n");
    138    for(p=head;p!=NULL;p=p->next){
    139       printf("%s\t%s\t%d\t%d\n",p->id,p->name,p->english,p->math);
    140    }
    141    system("pause");
    142 }
    143 
    144 
    145 void chaxun(struct student *head){
    146    char temp[10];
    147    system("cls");
    148    fflush(stdin);
    149    printf("请输入要查询学生的学号:");
    150    scanf("%s",temp);
    151    struct student *p;
    152    for(p=head;p!=NULL;p=p->next){
    153        if(strcmp(temp,p->id)==0)break;
    154    }
    155    if(p!=NULL){
    156       printf("学号\t姓名\t英语\t数学\n");
    157       printf("%s\t%s\t%d\t%d\n",p->id,p->name,p->english,p->math);
    158    }else{
    159       printf("没有查到学生\n");
    160    }
    161    system("pause");
    162 }
    163 
    164 
    165 
    166 struct student* tianjia(struct student *head){
    167    struct student *add=(struct student*)malloc(sizeof(struct student));
    168    struct student *p=NULL,*q=NULL;
    169    system("cls");
    170    fflush(stdin);
    171    printf("请输入学号:");
    172    scanf("%s",add->id);
    173 
    174    fflush(stdin);
    175    printf("请输入姓名:");
    176    scanf("%s",add->name);
    177 
    178    fflush(stdin);
    179    printf("请输入英语成绩:");
    180    scanf("%d",&(add->english));
    181 
    182    fflush(stdin);
    183    printf("请输入数学成绩:");
    184    scanf("%d",&(add->math));
    185 
    186    for(q=head;q!=NULL;q=q->next){
    187         if(strcmp(add->id,q->id)==0)
    188         {               
    189             printf("已存在该学生,此次输入无效");
    190             break;
    191         }
    192     }
    193    if(q==NULL){
    194         add->next=head;
    195         head=add;
    196         printf("添加数据成功\n");
    197     }
    198    
    199    system("pause");
    200    return head;
    201 }
    202 
    203 
    204 
    205 //删除链表节点
    206 struct student* deleteLink(struct student *head){
    207    struct student *p,*q;
    208    char tmp[10];
    209    system("cls");
    210 
    211    fflush(stdin);
    212    printf("请输入要删除学生的学号:\n");
    213    scanf("%s",tmp);
    214 
    215    for(p=head,q=NULL;p!=NULL;q=p,p=p->next){
    216        if(strcmp(tmp,p->id)==0)break;
    217    }
    218    if(p!=NULL){
    219        if(q==NULL){
    220           head=p->next;
    221        }else{
    222            q->next=p->next;
    223           
    224        } free(p);
    225    }
    226    printf("删除成功"); 
    227    system("pause");
    228    return head;
    229 }
    230 
    231 
    232 struct student* xiugai(struct student *head){
    233     char tmp[10];
    234     struct student *q;
    235     system("cls");
    236 
    237     fflush(stdin);
    238     printf("请输入要修改学生的学号:");
    239     scanf("%s",tmp);
    240 
    241     for(q=head;q!=NULL;q=q->next){
    242         if(strcmp(q->id,tmp)==0){
    243            break;
    244         }
    245     }
    246 
    247     if(q==NULL){
    248       printf("修改失败,不存在该学生\n");
    249     }else{
    250       
    251       fflush(stdin);
    252       printf("请输入姓名:");
    253       scanf("%s",q->name);
    254 
    255       fflush(stdin);
    256       printf("请输入英语成绩:");
    257       scanf("%d",&(q->english));
    258 
    259       fflush(stdin);
    260       printf("请输入数学成绩:");
    261       scanf("%d",&(q->math));
    262       
    263       printf("修改成功\n");
    264     }
    265 
    266     system("pause");
    267     return head;
    268 }
    269 bool isFile(char filename[]){
    270   FILE *fp;
    271   if((fp=fopen(filename,"rb"))==NULL){
    272     
    273      return false;
    274   }
    275   fseek(fp,0,SEEK_END);
    276   int length=ftell(fp)/(sizeof(struct student));
    277   if(length<1){
    278     return false;
    279   }
    280   fclose(fp);
    281   return true;
    282 }
    283 
    284 
    285 
    286 void storeData(struct student *head){
    287     struct student *q;
    288     FILE *fp;
    289     if((fp=fopen("Temp.dat","wb"))==NULL){
    290        printf("打开文件 Temp.dat 失败\n");
    291     }
    292     for(q=head;q!=NULL;q=q->next){
    293         
    294         fwrite(q,sizeof(struct student),1,fp);
    295     }
    296 
    297 
    298     fclose(fp);
    299     printf("存储数据成功");
    300 }
    301 
    302 struct student *readData(){
    303    jiemi();
    304    struct student *head,*q,*p;
    305    head=q=NULL; 
    306    int i=0;
    307    FILE *fp;
    308        if((fp=fopen("Temp.dat","rb"))==NULL){
    309        printf("打开文件 Temp.dat 失败\n");
    310     }fseek(fp,0,SEEK_END);
    311    int length=ftell(fp)/(sizeof(struct student));
    312    fseek(fp,0,SEEK_SET);
    313     while(i<length){
    314         
    315         p=(struct student*)malloc(sizeof(struct student));
    316 
    317         fread(p,sizeof(struct student),1,fp);
    318 
    319         if(head==NULL){
    320            head=q=p;
    321         }else{
    322            q->next=p;
    323            q=p;
    324         }  
    325         i++;
    326     }
    327     q->next=NULL;
    328     fclose(fp);
    329     return head;
    330     
    331 }

     运行截图:

    存在的不足:

      该程序还存在许多不足,比如说很多出错处理没有处理,比如所要求输入整形时输入字符型,输入超过范围的处理等。程序在处理数据比较小的时候较好,但如果处理数据过大就不是很适用。界面比较简单。

      

      

  • 相关阅读:
    Oracle 创建索引分区
    Shiro SessionManager会话管理器设计概念
    管理表分区
    Oracle 表分区策略
    Oracle 表分区
    参考Shiro的Session定期验证会话失效的线程池
    HDU 3555 Bomb (数位dp)
    POJ 3666 Making the Grade (动态规划)
    Gym
    POJ
  • 原文地址:https://www.cnblogs.com/cxyc/p/5272319.html
Copyright © 2011-2022 走看看