C语言实现学生成绩管理

  • 项目简介

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

  • 程序简示图

  • 功能介绍

1. 加密数据:

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

2.加密算法:

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

  如b为原文,a为加密后的密文,c代表密码,则

 加密:
a=b^c; 解密
a^c=>b^c^c=>b

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

 #define KEY 0x85

 void secretFile(char *srcfile,char *dstfile){
FILE *fp1,*fp2; if((fp1=fopen(srcfile,"rb"))==NULL){ //获取被加密文件指针
return ;
} if((fp2=fopen(dstfile,"wb"))==NULL){ //获取加密文件指针
return;
} fseek(fp1,,SEEK_END);
int length=ftell(fp1); //获取文件的长度 fseek(fp1,,SEEK_SET); char *p=(char *)malloc(sizeof(char)*length);
fread(p,sizeof(char),length,fp1);//将文件数据读入p所指内存空间 for(int i=;i<length;i++){
p[i]^=KEY;
} //异或加密 fwrite(p,sizeof(char),length,fp2);//将加密后的数据读入目标文件 fclose(fp1);
fclose(fp2);
}
调用加密函数
 void jiemi(){        //解密
FILE *fp;
if((fp=fopen("Temp.dat","wb"))==NULL){
return;
} //生成临时文件
fclose(fp);
secretFile("Data.dat","Temp.dat"); //解密到临时文件
} void jiami(){ //加密
FILE *fp;
if((fp=fopen("Data.dat","wb"))==NULL){
return;
}
fclose(fp);
secretFile("Temp.dat","Data.dat"); //加密到目标文件
remove("Temp.dat"); //删除临时文件
}

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

加密前的文件:

加密后的文件:

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

3.写入、读取文件

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

 struct student *readData(){
jiemi(); //调用解密,生成解密后的文件Temp.dat struct student *head,*q,*p;
head=q=NULL;
int i=;
FILE *fp;
if((fp=fopen("Temp.dat","rb"))==NULL){
printf("打开文件 Temp.dat 失败\n");
}
//获取文件指针 fseek(fp,,SEEK_END);
int length=ftell(fp)/(sizeof(struct student));
//获取文件长度,确定链表的长度
fseek(fp,,SEEK_SET); while(i<length){ p=(struct student*)malloc(sizeof(struct student)); fread(p,sizeof(struct student),,fp); //读数据到p if(head==NULL){ //生成头结点
head=q=p;
}else{
q->next=p; //在尾节点添加数据
q=p;
}
i++;
}
q->next=NULL; //尾节点置为空
fclose(fp);
return head; }

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

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

具体代码:

头文件head.h:

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h> #define KEY 0x85 //定义加密字符串 struct student{
char id[]; //学号
char name[]; //姓名
int math; //数学成绩
int english; //英语成绩
struct student *next;
}; //学生结构体 void secretFile(char *srcfile,char *dstfile);//加密函数
void jiemi(); //解密
void jiami(); //加密
bool isData(struct student *head,char tmp[]);//是否存在该节点
struct student* creatLink();//生成链表
struct student* findLink(struct student *head,char id[]);//查找节点
void infoDisplay(struct student *head);//查看所有节点信息
void chaxun(struct student *head);//查询学生信息
struct student* tianjia(struct student *head);//添加学生
struct student* deleteLink(struct student *head);//删除学生
struct student* xiugai(struct student *head);//修改学生信息
bool isFile(char filename[]);//判断是否存在文件
void storeData(struct student *head);//存储数据到文件
struct student *readData();//读入数据生成链表
33 void freeLink(struct sutdent *head);//释放链表

主函数main.cpp:

 #include"head.h"

 void menu(){
struct student *head=NULL;
system("cls");
if(false==isFile("Data.dat")){
printf("第一次进入:请先添加数据:\n");
head=creatLink(); } else{
head=readData(); }
int iSelect=;
while(iSelect!=){
system("cls");
printf("请输入选项:\n");
printf("1.查询成绩 2.添加成绩 3.删除成绩 4.修改成绩 5.数据一览 6.退出\n");
scanf("%d",&iSelect);
switch(iSelect){
case :chaxun(head);break;
case :head=deleteLink(head);break;
case :head=tianjia(head);break;
case :head=xiugai(head);break;
case :infoDisplay(head);break;
case :storeData(head);freeLink(head);jiami();system("pause");break;
default:printf("\n输入错误请重新输入:");system("pause");break;
}
}
} int main(){
menu();
return ;
}

具体函数function.cpp:

 #include"head.h"

 void freeLink(struct student *head){
struct student *p,*q;
p=head;
while(p!=NULL){
q=p;
p=p->next;
free(q);
}
} void secretFile(char *srcfile,char *dstfile){
FILE *fp1,*fp2;
if((fp1=fopen(srcfile,"rb"))==NULL){
return ;
}
if((fp2=fopen(dstfile,"wb"))==NULL){
return;
}
fseek(fp1,,SEEK_END);
int length=ftell(fp1);
fseek(fp1,,SEEK_SET);
char *p=(char *)malloc(sizeof(char)*length);
fread(p,sizeof(char),length,fp1);
for(int i=;i<length;i++){
p[i]^=KEY;
}
fwrite(p,sizeof(char),length,fp2);
fclose(fp1);
fclose(fp2);
} void jiemi(){
FILE *fp;
if((fp=fopen("Temp.dat","wb"))==NULL){
return;
}
fclose(fp);
secretFile("Data.dat","Temp.dat");
} void jiami(){
FILE *fp;
if((fp=fopen("Data.dat","wb"))==NULL){
return;
}
fclose(fp);
secretFile("Temp.dat","Data.dat");
remove("Temp.dat");
} bool isData(struct student *head,char tmp[]){
struct student *q;
printf("flag\n");
for(q=head;q!=NULL;q=q->next){
if(strcmp(tmp,q->id)==){
return true;
}
} return false;
} //创建链表
struct student* creatLink(){
struct student *head,*q,*p;
head=q=NULL;
char id[];
int i=; head=q=NULL;
while(){
printf("(#结束输入)\n请输入学号:");
scanf("%s",id);
if(strcmp("#",id)==){
break;
}
p=(struct student*)malloc(sizeof(struct student));
strcpy(p->id,id); fflush(stdin);
printf("请输入姓名:");
scanf("%s",p->name); fflush(stdin);
printf("请输入数学成绩:");
scanf("%d",&(p->math)); fflush(stdin);
printf("请输入英语成绩:");
scanf("%d",&(p->english));
if(head==NULL){
head=q=p;
q->next=NULL;
}else{
if(isData(head,p->id)==true){
printf("已经存在该学生,该次数据无效\n");
}
else{
q->next=p;
q=p;
q->next=NULL;
}
}
}
q->next=NULL;
return head;
} struct student* findLink(struct student *head,char id[]){
struct student *p;
for(p=head;p!=NULL;p=p->next){
if(strcmp(id,p->id)==)break;
}
if(p!=NULL){
return p;
}
return NULL;
} void infoDisplay(struct student *head){
struct student *p;
system("cls");
printf("学号\t姓名\t英语\t数学\n");
for(p=head;p!=NULL;p=p->next){
printf("%s\t%s\t%d\t%d\n",p->id,p->name,p->english,p->math);
}
system("pause");
} void chaxun(struct student *head){
char temp[];
system("cls");
fflush(stdin);
printf("请输入要查询学生的学号:");
scanf("%s",temp);
struct student *p;
for(p=head;p!=NULL;p=p->next){
if(strcmp(temp,p->id)==)break;
}
if(p!=NULL){
printf("学号\t姓名\t英语\t数学\n");
printf("%s\t%s\t%d\t%d\n",p->id,p->name,p->english,p->math);
}else{
printf("没有查到学生\n");
}
system("pause");
} struct student* tianjia(struct student *head){
struct student *add=(struct student*)malloc(sizeof(struct student));
struct student *p=NULL,*q=NULL;
system("cls");
fflush(stdin);
printf("请输入学号:");
scanf("%s",add->id); fflush(stdin);
printf("请输入姓名:");
scanf("%s",add->name); fflush(stdin);
printf("请输入英语成绩:");
scanf("%d",&(add->english)); fflush(stdin);
printf("请输入数学成绩:");
scanf("%d",&(add->math)); for(q=head;q!=NULL;q=q->next){
if(strcmp(add->id,q->id)==)
{
printf("已存在该学生,此次输入无效");
break;
}
}
if(q==NULL){
add->next=head;
head=add;
printf("添加数据成功\n");
} system("pause");
return head;
} //删除链表节点
struct student* deleteLink(struct student *head){
struct student *p,*q;
char tmp[];
system("cls"); fflush(stdin);
printf("请输入要删除学生的学号:\n");
scanf("%s",tmp); for(p=head,q=NULL;p!=NULL;q=p,p=p->next){
if(strcmp(tmp,p->id)==)break;
}
if(p!=NULL){
if(q==NULL){
head=p->next;
}else{
q->next=p->next; } free(p);
}
printf("删除成功");
system("pause");
return head;
} struct student* xiugai(struct student *head){
char tmp[];
struct student *q;
system("cls"); fflush(stdin);
printf("请输入要修改学生的学号:");
scanf("%s",tmp); for(q=head;q!=NULL;q=q->next){
if(strcmp(q->id,tmp)==){
break;
}
} if(q==NULL){
printf("修改失败,不存在该学生\n");
}else{ fflush(stdin);
printf("请输入姓名:");
scanf("%s",q->name); fflush(stdin);
printf("请输入英语成绩:");
scanf("%d",&(q->english)); fflush(stdin);
printf("请输入数学成绩:");
scanf("%d",&(q->math)); printf("修改成功\n");
} system("pause");
return head;
}
bool isFile(char filename[]){
FILE *fp;
if((fp=fopen(filename,"rb"))==NULL){ return false;
}
fseek(fp,,SEEK_END);
int length=ftell(fp)/(sizeof(struct student));
if(length<){
return false;
}
fclose(fp);
return true;
} void storeData(struct student *head){
struct student *q;
FILE *fp;
if((fp=fopen("Temp.dat","wb"))==NULL){
printf("打开文件 Temp.dat 失败\n");
}
for(q=head;q!=NULL;q=q->next){ fwrite(q,sizeof(struct student),,fp);
} fclose(fp);
printf("存储数据成功");
} struct student *readData(){
jiemi();
struct student *head,*q,*p;
head=q=NULL;
int i=;
FILE *fp;
if((fp=fopen("Temp.dat","rb"))==NULL){
printf("打开文件 Temp.dat 失败\n");
}fseek(fp,,SEEK_END);
int length=ftell(fp)/(sizeof(struct student));
fseek(fp,,SEEK_SET);
while(i<length){ p=(struct student*)malloc(sizeof(struct student)); fread(p,sizeof(struct student),,fp); if(head==NULL){
head=q=p;
}else{
q->next=p;
q=p;
}
i++;
}
q->next=NULL;
fclose(fp);
return head; }

运行截图:

存在的不足:

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

  

  

C语言文件实现学生成绩管理的更多相关文章

  1. 学生成绩管理C语言版

    [标题]学生成绩管理的设计与实现 [开发语言]C语言 [概要设计]使用结构体存储学生的学号.姓名和成绩信息,实现对学生成绩类的基本操作:增加.删除.查询.排序 [测试数据]按提示输入5组正确的正确的数 ...

  2. 学生成绩管理C++版

    [标题]学生成绩管理的设计与实现 [开发语言]C++ [主要技术]STL [概要设计]类名:student 类成员:No.Name.Math.Eng.Chn.Cpro.Sum 成员函数:getname ...

  3. JAVA课程设计 学生成绩管理

    学生成绩管理 可实现功能: 添加学生功能:姓名.学号.性别.出生年月日.(学号自动生成且唯一) 添加学生成绩功能:每个人都有数学.Java与体育四门课,可分课程输入成绩. 根据学生学号查找学生成绩功能 ...

  4. C语言项目:学生成绩管理系统

    C语言项目:学生成绩管理系统    1.数据结构:学生信息:学号.姓名.年龄.性别.3课成绩    2.功能:   (1)增加学生记录    (2)  删除学生记录    (3)  查找学生信息(学号 ...

  5. JAVA基础代码分享--学生成绩管理

    问题描述: 从键盘读入学生成绩,找出最高分,并输出学生成绩等级. 成绩>=最高分-10  等级为’A’   成绩>=最高分-20  等级为’B’ 成绩>=最高分-30  等级为’C’ ...

  6. JAVA课程设计个人博客 学生成绩管理 201521123001 张陈东芳

    1. 团队课程设计博客链接 http://www.cnblogs.com/kawajiang/p/7062407.html 2.个人负责模块或任务说明 我主要负责实现学生信息的添加功能.学生成绩的录入 ...

  7. 简易学生成绩管理管理系统(java描述)

    没正式学过java,但是系统学过C++后,初略的看了下java的基本语法,于是我就尝试着用java来写个简单的学生管理系统,功能不齐全,以后有空再补充吧. 写的时候定义了不同的包名字,如jeaven1 ...

  8. 开学考试学生成绩管理Java

    首先student类 package xuexi; public class Student { private String stunumber; private String name; priv ...

  9. JAVA课程设计个人博客 学生成绩管理 201521123023 戴建钊

    1. 团队课程设计博客链接 http://www.cnblogs.com/kawajiang/p/7062407.html 2.个人负责模块或任务说明 我主要负责实现随机生成10万个学生及其姓名.学号 ...

随机推荐

  1. L177 Arctic ice brings an understanding of ancient Europe’s economy

    Greenland's icy mountains are not an obvious place to search for an archive of economic history, but ...

  2. IOS中UITableViewCell使用详解

    IOS中UITableViewCell使用详解 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(N ...

  3. cobbler装机错误--Failed to create kernel channel,-22

    最近使用cobbler安装GPU的机器遇到了一个错误:Failed to create kernel channel,-22 经过各种搜索发现是英伟达的显卡与centos7的默认显卡驱动冲突导致. 网 ...

  4. graphql-yoga 项目简单使用&&集成docker

      graphql-yoga 是一个实现了grahql的框架,使用简单,便捷 具体源码参考github https://github.com/rongfengliang/graphql-yoga-do ...

  5. gpio_get_value的定义 (转)

    gpio_get_value等一系列函数,并非Linux标准函数,而是跟硬件相关的. 通常我们说的driver都是跟外围设备相关的,所以需要我们自己开发,但是这次我们说到的gpio是跟soc相关的,其 ...

  6. java 题

    [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分析:   兔子的规律为数列1 ...

  7. week3-栈和队列

    1.学习总结 2.PTA实验作业 2.1 题目1:7-1 jmu-报数游戏 2.2 设计思路(伪代码或流程图) 2.3 代码截图 2.4 PTA提交列表说明. 答案错误:error少了 !: 非零返回 ...

  8. 2018-2019-1 20165226《信息安全系统设计基础》 pwd命令的实现

    2018-2019-1 20165226<信息安全系统设计基础> pwd命令的实现 一.学习pwd 查看pwd 得知一个嫩过去文件路径的函数--getcwd i节点值 通过ls -i -a ...

  9. zabbix触发器函数 count

    转摘至梅总文章 一直没用过这个函数,今天研究了下,确实很有用(用过的忽略): 之前很多功能都是用max,min,avg曲线实现的,其实用count最合理(如典典刚用的高防持续N次ping超时).   ...

  10. Fri Oct 31 18:00:00 UTC+0800 2008转换为yyyy-mm-dd

    这个其实网上有很多例子,都是直接用js在前端做了时间处理,我的处理也一样,想要变成2008-3-31,就用下面的js直接可以处理 function Todate(num) { //Fri Oct 31 ...