Demo entry 6354518

hello

   

Submitted by anonymous on Apr 07, 2017 at 15:49
Language: C. Code size: 7.8 kB.

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

//学生信息管理

typedef struct Student
{
	int m_iNum;
	int m_iStuID;
	char m_cName[20];
	char m_cSex;
	int m_iAge;
	char m_cAddress[20];
	char m_iTel[12];
	struct Student *next;
};

typedef struct Student student;
typedef struct Student* pstudent;

void InitStudent(pstudent Stu);		//初始化学生基本信息
int AddStudent(pstudent AllStu,pstudent Stu,int SerialNum);		//添加学生基本信息
pstudent FindStudent(pstudent AllStu,int flag);		//查询学生基本信息
void GetStudent(pstudent Stu);	//获取学生基本信息
void ModifyStudent(pstudent Stu);	//修改学生基本信息
void DeleteStudent(pstudent AllStu,pstudent p);		//删除学生基本信息
void SaveStudent(pstudent AllStu);			//保存文件
void PrintOneStudent(pstudent Stu);//打印一个学生的信息
void PrintAllStudent(pstudent AllStu);//打印所有学生的信息
pstudent LoadStudent();//从文件中读取学生信息


int main()
{
	int status = 1;
	int flag;//用来判断返回值是否符合
	int NumOfStudent = 0,i=0;
	pstudent AllStu;
	pstudent p;
	AllStu = (pstudent) malloc(sizeof(student));
	InitStudent(AllStu);
	while (1)
	{
		printf("What do you want to do?\n");
		printf("1 - 输入一堆学生  \n2 - 找一个学生 \n3 - 在指定位置添加一个学生 \n4 - 修改学生基本信息 \n5 - 删除学生基本信息 \n6 - 打印所有学生的信息\n7 - 保存学生信息 \n8 - 读取学生的信息\n9 - 退出程序\n");
		scanf("%d", &status);
		flag = 1;
		switch (status)
		{
			case 1: //输入一堆学生
				printf("你要添加几名学生呢:\n");//输入一堆学生
				scanf("%d", &NumOfStudent);
				for (i = 0; i < NumOfStudent; i++)
				{
					printf("正在输入第%d位学生\n", i + 1);
					pstudent Stu;
					Stu = (pstudent) malloc(sizeof(student));
					GetStudent(Stu);
					AddStudent(AllStu, Stu, 0);
				}
				break;
			case 2://找一个学生并打印
				printf("你是要通过序号查找还是学号还是名字(请输入1/2/3):\n");
				scanf("%d", &flag);
				p= FindStudent(AllStu, flag);
				if (p!=NULL)
				{
				PrintOneStudent(p);
				}
				break;
			case 3://在指定位置添加一个学生
				printf("请输入要添加学生的序号:\n");
				scanf("%d", &NumOfStudent);
				pstudent Stu;
				Stu = (pstudent) malloc(sizeof(student));
				Stu->m_iNum = NumOfStudent;
				GetStudent(Stu);
				flag = AddStudent(AllStu, Stu, NumOfStudent);
				if (flag==0)
				{
					printf("操作失败,序号有重复!\n");
				}
				break;
			case 4://修改学生基本信息
				printf("你是要通过序号还是学号还是名字来找到要修改的学生(请输入1/2/3):\n");
				scanf("%d", &flag);
				p = FindStudent(AllStu, flag);
				if (p!=NULL)
				{
					ModifyStudent(p);
				}
				break;
			case 5://删除一个学生
				printf("首先你要找到那个学生,你要通过序号还是学号还是名字来找到要修改的学生(请输入1/2/3):\n");
				scanf("%d", &flag);
				p = FindStudent(AllStu, flag);
				if (p!=NULL)
				{
				DeleteStudent(AllStu,p);
				}
				break;
			case 6://打印所有学生
				PrintAllStudent(AllStu);
				break;
			case 7://保存所有学生
				SaveStudent(AllStu);
				break;
			case 8://保存所有学生
				free(AllStu);
				AllStu = LoadStudent();
				break;
			case 9://退出
				exit(0); 
		}
	}
}

void InitStudent(pstudent Stu)
{
	Stu->m_iNum = -1;
	Stu->m_iAge = -1;
	Stu->m_iStuID = -1;
	Stu->next = NULL;
}

void GetStudent(pstudent Stu)
{
	/*printf("Please input the serial number:\n");
	scanf("%d", &Stu->m_iNum);*/
	printf("请输入学生的学号:\n");
	scanf("%d", &Stu->m_iStuID);
	getchar();				//接收回车符,要不然后面的gets会接收,然后跳过
	printf("请输入学生的英文名:\n");
	gets(Stu->m_cName);
	printf("TA的性别是什么F代表女性,M代表男性:\n");
	Stu->m_cSex = getchar();
	printf("学生几岁了:\n");
	scanf("%d", &Stu->m_iAge);
	getchar();			//接收回车符,要不然后面的gets会接收,然后跳过
	printf("请输入学生的英文地址:\n");
	gets(Stu->m_cAddress);
	printf("学生的电话:\n");
	gets(Stu->m_iTel);
	Stu->next = NULL;
}

int AddStudent(pstudent AllStu, pstudent Stu, int SerialNum)
{
	pstudent p,q;
	int flag = 0;
	p = AllStu;
	int sum=1;
	if (SerialNum == 0)						//没有指定序号的时候插入到最后
	{
		while (p->next != NULL)			//找到尾节点
		{
			sum++;								//计数器,算出当前结点在第几格,然后自动安排序号
			p = p->next;
		}
		Stu->m_iNum = sum;
		p->next = Stu;
	}
	else
	{										//指定序号时,插入到合适的地方
		q = p;
		while (p != NULL)		
		{
			if (p->m_iNum<SerialNum)			//如果p的序号比较小
			{
				q = p;						//q等于p后,p向后移一位
				p = p->next;
			}
			else if (p->m_iNum>SerialNum)
			{
				//Stu->m_iNum = SerialNum;
				Stu->next = q->next;			//将
				q->next = Stu;
				flag++;
				break;
			}
			else return 0;//假如序号和原来链表中的重复了,就返回0;
		}
		if (flag==0)
		{
			q->next = Stu;
		}
		return 1;
	}
}

pstudent FindStudent(pstudent AllStu, int flag)//寻找那个学生并打印
{
	pstudent p;
	int num = 0;
	char name[20];
	int sign = 0;//作为是否找到了那个学生的标志
	p = AllStu;
	printf("请输入:\n");
	switch (flag)
	{
		case 1://第一种情况:按序号查找
			scanf("%d", &num);
			while (p != NULL)
			{
				if (p->m_iNum == num)//如果找到了那个学生,打印他的信息,并且跳出函数
				{
					return p;//如果找到那个学生,则直接返回那个学生的指针
				}
				else
					p = p->next;
			}
				printf("你找的人数据库里没有哦!\n");
			break;
		case 2://第二种情况:按学号查找
			scanf("%d", &num);
			while (p != NULL)
			{
				if (p->m_iStuID == num)//如果找到了那个学生,打印他的信息,并且跳出函数
				{
					return p;//如果找到那个学生,则直接返回那个学生的指针
				}
				else
					p = p->next;
			}
			printf("你找的人数据库里没有哦!\n");//如果到这里还没有返回指针,则表明找不到该学生了
			break;
		case 3://第三种情况:按名字查找
			getchar();//接收前面的回车键
			gets(name);
			while (p != NULL)
			{
				if (strcmp(name,p->m_cName)==0)//如果找到了那个学生,打印他的信息,并且跳出函数
				{
					return p;//如果找到那个学生,则直接返回那个学生的指针
				}
				else
					p = p->next;
			}
				printf("你找的人数据库里没有哦!\n");
			break;
	}
	return NULL;
}

void PrintOneStudent(pstudent Stu)
{
	printf("学生序号是:%d\n学号:%d\n姓名:%s\n性别:%c\n年龄:%d\n家庭住址:%s\n电话:%s\n", Stu->m_iNum, Stu->m_iStuID, Stu->m_cName, Stu->m_cSex, Stu->m_iAge, Stu->m_cAddress, Stu->m_iTel);
}

void ModifyStudent(pstudent Stu)
{
	char flag[7];
	int sign1=0,sign2=0;
	printf("请按顺序输入要修改的量,\n顺序为:学号、姓名、性别、年龄、家庭地址、电话,\n用1表示需要修改,0表示不需要修改,\n如我需要修改姓名和年龄,则输入010100\n");
	getchar();
	gets(flag);
	if (flag[0] == 49)
	{
		printf("请输入新的学生学号:\n");
		scanf("%d", &Stu->m_iStuID);
	}
	if (flag[1] == 49)
	{
		printf("请输入新的学生姓名:\n");
		getchar();
		gets(Stu->m_cName);
		sign1++;
	}
	if (flag[2] == 49)
	{
		printf("请输入新的学生性别:\n");
		Stu->m_cSex = getchar();
	}
	if (flag[3] == 49)
	{
		printf("请输入新的学生年龄:\n");
		scanf("%d", &Stu->m_iAge);
	}
	if (flag[4] == 49)
	{
		printf("请输入新的学生家庭住址:\n");
		if (sign1==0)//sign==0则表明前面的名字没有修改,也就是没有用到gets,所以回车键不会被吸收,要主动吸收
		{
		getchar();
		}
		gets(Stu->m_cAddress);
		sign2++;
	}
	if (flag[5] == 49)
	{
		printf("请输入新的学生电话:\n");
		if (sign2==0)//sign==0则表明前面的家庭住址没有修改,也就是没有用到gets,所以回车键不会被吸收,要主动吸收
		{
		getchar();
		}
		gets(Stu->m_iTel);
	}
	printf("新的学生信息为:\n");
	PrintOneStudent(Stu);
}

void DeleteStudent(pstudent AllStu, pstudent p)
{
	pstudent q;
	q = AllStu;
	while (q->next != p)q = q->next;
	q->next = p->next;
	free(p);
}

void PrintAllStudent(pstudent AllStu)
{
	pstudent Stu;
	Stu = AllStu->next;
	printf("学生序号      学号        姓名          性别   年龄      家庭住址           电话  \n");
	while (Stu!=NULL)
	{
		printf("%5d %15d    %-15s %c      %d       %-15s %s \n", Stu->m_iNum, Stu->m_iStuID, Stu->m_cName, Stu->m_cSex, Stu->m_iAge, Stu->m_cAddress, Stu->m_iTel);
		Stu = Stu->next;
	}
}

void SaveStudent(pstudent AllStu)
{
	FILE *fp;
	fp = fopen("test.txt", "wb");
	while (AllStu != NULL)
	{
		fwrite(AllStu, sizeof(struct Student) - 4, 1, fp);
		AllStu = AllStu->next;
	}
	fclose(fp);
	printf("保存完毕!\n");
}

pstudent LoadStudent()
{
	FILE *fp;
	fp = fopen("test.txt", "rb");
	pstudent pStu = NULL;
	pstudent head;
	while (!feof(fp))
	{
		if (pStu != NULL)
			pStu = pStu->next = (pstudent)malloc(sizeof(student));
		else	
			head = pStu = (pstudent)malloc(sizeof(student));

		pStu->next = NULL;
		fread(pStu, sizeof(struct Student) - 4, 1, fp);
	}

	// feof()函数很迷 会导致多读一次数据
	// 所以直接删除最后一个元素
	pStu = head;
	while (pStu->next->next != NULL)
		pStu = pStu->next;
	free(pStu->next);
	pStu->next = NULL;

	fclose(fp);
	printf("读取完毕!\n");
	return head;
}

This snippet took 0.02 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).