C语言管理系统&&文件

核心是链表的增删改查,然后增加了密码登陆的部分和一点点文件,需要注意的是文件要和源码在同一目录下,否则很容易找不到文件(补充一个报错函数perror,比如fp=fopen("student.txt","r");   //只读
    if(!fp){
        printf("文件打开失败!\n");    出现文件打开失败时,可以将printf改为perror,perror("....");在运行,会显示出是因为找不到文件)

代码如下

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct Student
{
   int num;
   char name[20];
   float grade;	
   char mima[20]; 
   struct Student *next;
 } ;    //定义结构体
 struct Student *phead=NULL;
 int count=0;   //全局变量,计算文件内数据值
 int c;
void Creatphead()
 {
 	phead=(struct Student *)malloc(sizeof(struct Student));
 	if(!phead){
 		printf("头节点创建失败\n");
		 return; 
	 }
	 phead->next=NULL;
  } 
//无论老师还是学生,都要登陆账号
void denglu(struct Student *phead)     
{
	
	int a;
	char agrc[20];
	struct Student *p=phead->next;
	printf("请输入你的账号:"); 
	scanf("%d",&a);
	while(p->num!=a){
	p=p->next;
	c++;
    }
    printf("请输入你的密码:");
   scanf("%s",agrc);
   if((strcmp(agrc,p->mima)))   //strcmp函数,相同时会返回0
   {
   	printf("账号或密码错误\n"); 
   	exit(1); 
   }
   else{
   	printf("密码正确\a\n");
	   
   }
}
//inti部分实现读取文件内容
void inti(struct  Student *phead)
{
	
	FILE *fp=NULL;
	struct Student *p=NULL;
	struct Student *q=phead;
	fp=fopen("student.txt","r");   //只读
	if(!fp){
		printf("文件打开失败!\n");
		exit(0);
	}
	while(1){
		p=(struct Student *)malloc(sizeof(struct Student));
		fscanf(fp,"%d%s%f%s",&p->num,&p->name,&p->grade,&p->mima);//这里我用的是fscanf
		p->next=NULL;
		if(feof(fp)){     //feof用来判断文件指针是否到文件末尾,到末尾则返回1,否则返回0
			break;
		}
		count++;
		q->next=p;
		q=q->next;
	}
}
void add(struct Student *phead)
{
	struct Student *p=NULL;
	struct Student *q=phead;
	while(q->next!=NULL){
		q=q->next;
    }
		p=(struct Student *)malloc(sizeof(struct Student));
		printf("请输入学号:");
		scanf("%d",&p->num);
		printf("请输入姓名:");
		scanf("%s",p->name);
		printf("请输入成绩:");
		scanf("%f",&p->grade);
		printf("请输入密码:");
		scanf("%s",p->mima);
		p->next=NULL;
		q->next=p;   //这里用的是尾插
		 
}  
//是整体输出,其实就是链表的遍历
void output(struct Student *phead)
{
	struct Student *p=phead->next;
	
	while(p){
		printf("*******************************************\n");
		printf("姓名:%s\t    学号:%d\t   成绩:%f\t   密码:%s\n",p->name,p->num,p->grade,p->mima);    //\t制表符,看起来更整齐
		printf("*******************************************\n");
		p=p->next;
	}
	
}
//删除部分
void delate(struct Student *phead)
{
	int a;
	struct Student *p,*pre;
	printf("请输入要删除学生的学号:");
	scanf("%d",&a) ;
	p=phead->next;
	while(p->num!=a){
		pre=p;      //删除一个后前后节点相连,用pre保存前一个结点
		p=p->next;     //先等于再移动,保证pre是p的前一个
	}
	pre->next=p->next;
	free(p);
}
void amend(struct Student *phead)
{
	int a;
	printf("请输入要修改学生的学号:");
	scanf("%d",&a) ;
	struct Student *p=phead->next;
	while(p->num!=a){
		p=p->next;
	}
	printf("请输入学号:");
	scanf("%d",&p->num);
	printf("请输入姓名:");
	scanf("%s",p->name);
	printf("请输入成绩:");
	scanf("%f",&p->grade);
	printf("请输入密码:");
	scanf("%s",p->mima);
}
//输出这里只输出一条数据
void query(struct Student *phead)
{
	int a;
	struct Student *p=phead->next;
	printf("请输入要查找学生的学号:"); 
	scanf("%d",&a);
	while(p->num!=a){
	p=p->next;
    }
 	printf("姓名:%s\t    学号:%d\t   成绩:%f\t    密码:%s\n",p->name,p->num,p->grade,p->mima);   
}



void fush(struct  Student *phead)
{
	FILE *fp=NULL;
	struct Student *p=phead->next;
	fp=fopen("student.txt","w");
	while(p!=NULL){
		fprintf(fp,"%d\t%s\t%f\t%s\n",p->num,p->name,p->grade,p->mima);
		p=p->next;
	}
	printf("数据保存成功!\n"); 
}
//排序功能,应用于链表的冒泡排序
void asort(struct Student *phead)
{
	
	struct Student *p,*q,*pre;
	p=phead->next;
	q=NULL;
	if(p==NULL||p->next==NULL){
	
		return;
	}
	while(p!=q){
		while(p->next!=q){
			if(p->grade>p->next->grade){   //这里看起来有点乱哈
				float t=p->grade;
				p->grade=p->next->grade;
				p->next->grade=t;
				int a=p->num;
				p->num=p->next->num;
				p->next->num=a;
				pre=p;
				strcpy(pre->name,p->name);     //字符串的交换用的是strcpy,把后面的字符串赋 
                                                给前面的,借助中间指针pre实现交换
				strcpy(p->name,p->next->name);
				strcpy(p->next->name,pre->name);
				strcpy(pre->mima,p->mima);
				strcpy(p->mima,p->next->mima);
				strcpy(p->next->mima,pre->mima);
			}
			p=p->next;
		}
		q=p;
		p=phead->next;
	}
}
void student(struct Student *phead)
{
	system("cls");   //清屏函数
	int i;
	printf("\t\t\t欢迎使用学生查询系统\n");   //学生只可以查成绩和位次
	denglu(phead);
	query(phead);
	printf("是否要查看自己的位次:请选择(1.看/2,不看)\n"); 
	scanf("%d",&i);
	switch(i) {
		case 1:printf("\n%d\n",c+1);
		case 2:exit(0); 
	}
	
}
void teacher(struct Student *phead)
{
	system("cls");
	denglu(phead);
	printf("目前共有%d条数据\n",count); 
	int a;
	printf("\t\t\t欢迎使用学生管理系统\n");
	printf("\t\t\t/***********************/\n");  
	printf("\t\t\t|1.添加数据   2.删除信息|\n");
	printf("\t\t\t|3.修改数据   4.查找数据|\n");
	printf("\t\t\t|5.显示所有   6.排序    |\n");
	printf("\t\t\t|7.数据存档   8.退出程序|\n");
	printf("\t\t\t/***********************/\n");
	while(1){
		printf("\t请输入您的选择:");
		scanf("%d",&a); 
		switch(a){
		case 1:add(phead);break;
		case 2:delate(phead);break;
		case 3:amend(phead);break;
		case 4:query(phead);break;
		case 5:output(phead);break;
		case 6:asort(phead);break;
		case 7:fush(phead);break;
		case 8:exit(0) ;
		
	    }
    }
   
}
//人机交互面板
void creatface(struct Student *phead)
{
	int a;
	inti(phead);
	printf("\t\t\t欢迎使用学生管理系统\n");
	printf("\t\t\t请选择你是学生还是教师 :  1.(教师) 2.(学生)");
	scanf("%d",&a);
	switch(a){
		case 1:teacher(phead);break;
		case 2:student(phead);break;
	}
}
int main()
{
	Creatphead();
    creatface(phead);
	return 0;
}

 

顺带回顾一下文件的知识,读写文件也可以用fwrite,fread,数据块读写操作

void rewind(FILE *fp)可以将文件指针移到文件的开始位置,比如在文件末尾添加数据后调用

rewind使之回到开始的位置,再从头循环逐个显示当前文件的内容

int fseek(FILE *fp,long offset,int whence)文件指针由whence的地址移到offset的地址.fseek(fp,sizeof(struct stu)*n,0),文件指针由0后移n个数据记录的地址,也就是移到第n个数据处。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值