C语言文件实现学生成绩管理
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语言文件实现学生成绩管理的更多相关文章
- 学生成绩管理C语言版
[标题]学生成绩管理的设计与实现 [开发语言]C语言 [概要设计]使用结构体存储学生的学号.姓名和成绩信息,实现对学生成绩类的基本操作:增加.删除.查询.排序 [测试数据]按提示输入5组正确的正确的数 ...
- 学生成绩管理C++版
[标题]学生成绩管理的设计与实现 [开发语言]C++ [主要技术]STL [概要设计]类名:student 类成员:No.Name.Math.Eng.Chn.Cpro.Sum 成员函数:getname ...
- JAVA课程设计 学生成绩管理
学生成绩管理 可实现功能: 添加学生功能:姓名.学号.性别.出生年月日.(学号自动生成且唯一) 添加学生成绩功能:每个人都有数学.Java与体育四门课,可分课程输入成绩. 根据学生学号查找学生成绩功能 ...
- C语言项目:学生成绩管理系统
C语言项目:学生成绩管理系统 1.数据结构:学生信息:学号.姓名.年龄.性别.3课成绩 2.功能: (1)增加学生记录 (2) 删除学生记录 (3) 查找学生信息(学号 ...
- JAVA基础代码分享--学生成绩管理
问题描述: 从键盘读入学生成绩,找出最高分,并输出学生成绩等级. 成绩>=最高分-10 等级为’A’ 成绩>=最高分-20 等级为’B’ 成绩>=最高分-30 等级为’C’ ...
- JAVA课程设计个人博客 学生成绩管理 201521123001 张陈东芳
1. 团队课程设计博客链接 http://www.cnblogs.com/kawajiang/p/7062407.html 2.个人负责模块或任务说明 我主要负责实现学生信息的添加功能.学生成绩的录入 ...
- 简易学生成绩管理管理系统(java描述)
没正式学过java,但是系统学过C++后,初略的看了下java的基本语法,于是我就尝试着用java来写个简单的学生管理系统,功能不齐全,以后有空再补充吧. 写的时候定义了不同的包名字,如jeaven1 ...
- 开学考试学生成绩管理Java
首先student类 package xuexi; public class Student { private String stunumber; private String name; priv ...
- JAVA课程设计个人博客 学生成绩管理 201521123023 戴建钊
1. 团队课程设计博客链接 http://www.cnblogs.com/kawajiang/p/7062407.html 2.个人负责模块或任务说明 我主要负责实现随机生成10万个学生及其姓名.学号 ...
随机推荐
- 身份证&银行卡识别方案
一. 调用第三方服务 腾讯云OCR识别: 实现方法:Post图片 URL到腾讯云服务器.Post图片文件 到腾讯云服务器 b. 报价: 月接口调用总量 0<调用量≤1000 1000&l ...
- Java 线程面试题 Top 50(转 ImportNew)
不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎.大多数待遇丰厚的Java开发职位都要求开发者精通多线程 ...
- 二叉树的前序、中序、后序遍历 python
话不多说,直接上代码 class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None cl ...
- tensorflow中summary操作
tf中 tensorboard 工具通过读取在网络训练过程中保存到本地的日志文件实现数据可视化,日志数据保存主要用到 tf.summary 中的方法. tf.summary中summary是tf中的一 ...
- 片段的findFragmentById
class类名 名字 = calss类名 getFragmentManager().findFragmentById(R.id.布局id) 因为需要获取到片段的管理者,才可以去寻找到相应的布局.
- debian 安装deb软件
deb包 deb包是debian,ubuntu等LINUX发行版的软件安装包,是类似于rpm的软件包,而非debian,ubuntu系统不推荐使用deb软件包,因为要解决软件包依赖问题,安装也比较麻烦 ...
- 关于cookie和session的使用和理解
由于项目需要,最近用session容器比较多,传载的同时加上了自己的一些理解,不足之处还请大家补充和纠正. 一.cookie机制和session机制的区别 ********************** ...
- Java进行数据库导出导入 亲测可用
/** * @param hostIP ip地址,可以是本机也可以是远程 * @param userName 数据库的用户名 * @param password 数据库的密码 * @param sav ...
- scrapy多线程文件下载
在爬取数据时有时候有些文件数据需要爬取下载下来使用多线程下载可以让程序跑的更快点. scrapy中有个扩展可以使用扩展模块来实现下载. 在自己的spider中加入 custom_settings cl ...
- ballerina 学习二十二 弹性服务
主要包含断路器模式,负载均衡模式,故障转移,重试 Circuit Breaker 参考代码 import ballerina/http; import ballerina/log; import ba ...
