文档库 最新最全的文档下载
当前位置:文档库 › 学生信息管理系统(vc)

学生信息管理系统(vc)

// student1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include
#include
#include

#define CLASS 6
#define MAXID 10
#define MAXNAME 15
#define MALLOC (Student*) malloc(sizeof(Student))/*定义产生新结点的宏*/

/* 学生数据结构 */
typedef struct node
{
char id[20];
char name[15];
int score[CLASS];
int sum;
double ave;
struct node *next;
} Student;

/* 头指针 */
Student *head = NULL;
/* 临时指针 */
Student *tmp = NULL;
/* 课程名称 */
char CLASSNAME[CLASS][30] = {"物理", "化学", "计算机", "英语", "数学", "体育"};
/* 命令开关 */
int SWITCH[16] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/*switch[1]初始化标志,switch[6]文件保存标志,switch[8]总分平均分计算标志,switch[12]追加记录标志*/

/* 函数声明 */
int Menu(); /*菜单switch函数*/
Student* Init(); /*初始化程序*/

int CheckID(char*);/*检查id是否超出范围*/
int CheckName(char*);/*检查姓名是否规范*/
int CheakScore(int score);/*检查分数是否超出范围*/
int IsSameID(char*);/*检查id是否重复*/

Student* SearchID(char*);/*按id查找结点*/
Student* SearchName(char*);/*按姓名查找结点*/
void DeleteNode(Student*);/*删除结点*/
void SearchDeleteNode();/* 按学号或姓名查找删除节点 */

void InsertBefore();/*头插法插入结点*/
void InputNodeInfo(Student*); /*读取用户输入的学生信息*/
void InputList(); /*读取多个学生信息*/
void OutputNodeInfo(Student*);/*显示学生信息*/
void OutList();/*显示多个学生信息*/
Student* SearchFrontNode(Student*);/*查找前一结点*/
void SearchPrintNode();/* 按姓名查找记录并打印 */
void Compute();/* 计算总分和均分 */
int CmpID(Student*, Student*, int);/*比较两个id*/
int CmpSum(Student*, Student*, int);
int CmpScore(Student*, Student*, int);
Student* SearchMaxNode(int (*cmp)(Student*, Student*, int), int);/* 选择最大元素 */
Student* Sort(int (*cmp)(Student*, Student*, int), int);/* 排序 */
void OutputToFile(FILE*, Student*, int);/* 输出p指向节点的信息到文件 */
void InsertAfter(Student*);/* 将s插入链表尾部 */
void SaveToFile();/* 保存到文件 */
void LoadFile();/* 从文件中读入记录 */
void CopyFile(); /* 复制文件 */
void InsertToFile();/* 追加记录到文件中 */
void FreeList(Student* p);
void Stat();
void Quit();

/* 主函数 */
int main()
{
int n;

while (1)
{
n = Menu();
{
if (n == 1 || n == 15 || SWITCH[1])
{
switch (n)
{
/* 执行初始化 */
case 1:
head = Init();
printf("初始化成功\n");
break;
/* 创建链表 */

case 2:
InputList();
break;
/* 删除记录 */
case 3:
SearchDeleteNode();
break;
/* 显示全部记录 */
case 4:
system("cls"); /*system: int system(char *command)*/
/*system("pause")可以实现冻结屏幕,便于观察程序的执行结果;system("CLS")可以实现清屏操作*/
OutList();
break;
/* 查找记录 */
case 5:
SearchPrintNode();
break;
/* 保存文件 */
case 6:
SaveToFile();
break;
/* 读文件 */
case 7:
if (SWITCH[6])
{
head = Init();
LoadFile();
}
else
{
printf("当前文件未保存\n");
}
break;
/* 计算总分和均分 */
case 8:
Compute();
SWITCH[8] = 1;
printf("计算完毕\n");
break;
/* 插入记录 */
case 9:
InsertBefore();
SWITCH[6] = 0;
SWITCH[8] = 0;
break;
/* 复制文件 */
case 10:
CopyFile();
break;
/* 排序 */
case 11:
if (SWITCH[8])
{
head = Sort(CmpSum, 0);
system("cls");
OutList();
}
else
{
printf("请先计算总分!\n");
}
break;
/* 追加记录 */
case 12:
InsertToFile();
SWITCH[6] = 0;
printf("追加完毕!\n");
break;
/* 索引 */
case 13:
if (SWITCH[8])
{
head = Sort(CmpID, 0);
system("cls");
OutList();
}
else
{

printf("请先计算总分!\n");
}
break;
/* 分类合计 */
case 14:
system("cls");
Stat();
break;
/* 结束 */
case 15:
Quit();
break;
default:
printf("无效命令!\n");
fflush(stdin); /*标准输入缓存(称为STDIN),通常是连接到键盘*/
/*fflush:清除文件缓冲区,文件以写方式打开时将缓冲区内容写入文件*/
}
system("pause");
}
else
{
printf("你必须首先初始化!\n");
system("pause");
}
}
}

system("pause");
return 0;
}

/* 菜单 */
int Menu()
{
int n;
system("cls");
fflush(stdin);
printf("【01】 初始化\n");
printf("【02】 输入学生信息\n");
printf("【03】 查找学号或姓名删除信息\n");
printf("【04】 打印全部学生信息\n");
printf("【05】 按姓名查找学生信息\n");
printf("【06】 保存到文件\n");
printf("【07】 从文件中读取学生信息\n");
printf("【08】 计算所有学生的总分和平均分\n");
printf("【09】 插入一个学生信息到链表中\n");
printf("【10】 复制文件\n");
printf("【11】 按总分排序并打印学生信息\n");
printf("【12】 追加一个学生信息到文件中\n");
printf("【13】 按学号索引学生信息\n");
printf("【14】 分类汇总\n");
printf("【15】 退出\n");
printf("请输入命令编号: ");
scanf("%d", &n);
return n;
}

/* 初始化 */
Student* Init()
{
int i;
Student *head;
head = MALLOC;
head->next = NULL;

/* 命令开关初始化 */
for (i = 1; i < 16; i++)
{
SWITCH[i] = 0;
}

SWITCH[1] = 1;
SWITCH[6] = 1;
return head;
}

/* 检查学号 */
int CheckID(char* s)
{
int i;

if (strlen(s) == 0 || strlen(s) > MAXID) return 0;

for (i = 0; i < strlen(s); i++)
{
if (s[i] < '0' || s[i] > '9') return 0;
}

return 1;
}

/* 检查姓名 */
int CheckName(char* s)
{
int i;

if (strlen(s) == 0 || strlen(s) > MAXNAME) return 0;

for (i = 0; i < strlen(s); i++)
{
if (!(s[i] >= 'a' && s[i] <= 'z' || s[i] >= 'A' && s[i] <= 'Z')) return 0;
}

return 1;
}

/* 检查分数 */
int CheakScore(int score)
{
if (score > 100 || score <= 0) return 0;
return 1;
}

/* 检查相同学号 */
int IsSameID(char* s)
{
Student *p = head->next;
while(p != NULL)
{
if (strcmp(s, p->id) == 0) return 1;
p = p

->next;
}
return 0;
}

/* 给p指向的节点输入信息 */
void InputNodeInfo(Student* p)
{
fflush(stdin);

/* 学号 */
printf("\n请输入学号: ");
do
{
gets(p->id);

if (!CheckID(p->id))
{
printf("数据违法,请重新输入学号: ");
}
else if (IsSameID(p->id))
{
printf("已存在此学号,请重新输入: ");
}
}while (!(CheckID(p->id) && !IsSameID(p->id)));

/* 姓名 */
printf("请输入姓名: ");
do
{
gets(p->name);

if (!CheckName(p->name))
{
printf("数据违法,请重新输入姓名: ");
}
}
while (!CheckName(p->name));

/* 成绩 */
int i;
for (i = 0; i < CLASS; i++)
{
printf("请输入 %s 成绩: ", CLASSNAME[i]);
do
{
fflush(stdin);
scanf("%d", &p->score[i]);

if (!CheakScore(p->score[i]))
{
printf("数据违法,请重新输入 %s 成绩: ", CLASSNAME[i]);
}
}
while (!CheakScore(p->score[i]));
}

/* 总分及平均分 */
p->sum = -1;
p->ave = -1;
}

/* 输出p指向节点的信息 */
void OutputNodeInfo(Student* p)
{
int i;
printf("\n");
printf("姓名: %s\n", p->name);
printf("学号: %s\n", p->id);

for (i = 0; i < CLASS; i++)
{
printf("%s 成绩: %d\n", CLASSNAME[i], p->score[i]);
}

/* 计算过才输出 */
if (SWITCH[8]) printf("总分: %d\n", p->sum);
if (SWITCH[8]) printf("平均分: %.2lf\n", p->ave);
}

/* 返回r的前一个节点 */
Student* SearchFrontNode(Student* r)
{
Student *p = head;
while (p->next != r) p = p->next; /*查找student*r的前一单元*/
return p;
}

/* 删除r指向的节点 */
void DeleteNode(Student* r)
{
Student *p = SearchFrontNode(r);
p->next = r->next;
}

/* 头插法插入节点 */
void InsertBefore()
{
Student *s = MALLOC;
InputNodeInfo(s);
s->next = head->next;
head->next = s;
}

/* 输入链表 */
void InputList()
{
int n;
printf("有多少个学生信息要输入? ");
scanf("%d", &n);

while (n--)
{
InsertBefore();
}
}

/* 按学号查找 */
Student* SearchID(char* id)
{
Student *p = head->next;

while (p != NULL)
{
if (strcmp(p->id, id) == 0) break;
p = p->next;
}

return p;
}

/* 按姓名查找 */
Student* SearchName(char* name)
{
Student *p = head->next;

while (p != NULL)
{
if (strcmp(p->name, name) == 0) break;
p = p->next;
}

return p;
}

/* 按学号或姓名查找删除节点 */
void SearchDeleteNode()
{
Student *p;
fflush(stdin);
char str[20];
char sure[20];

/* 输入合法性判断 */
printf("请

输入你要删除的学生的 姓名 或 学号: ");
do
{
gets(str);

if (!(CheckID(str) || CheckName(str)))
{
printf("数据违法,请重新输入姓名或学号: ");
}
}
while (!(CheckID(str) || CheckName(str)));

/* 判断是姓名还是学号 */
if (str[0] >= '0' && str[0] <= '9')
{
p = SearchID(str);

if (p == NULL)
{
printf("对不起,找不到这个学号\n");
}
else
{
OutputNodeInfo(p);
printf("确认删除? (输入\"y\"确认,任意键取消): ");
if (strcmp(gets(sure), "y") == 0)
{
DeleteNode(p);
printf("删除成功\n");
SWITCH[6] = 0;
}
fflush(stdin);
}
}
else
{
p = SearchName(str);

if (p == NULL)
{
printf("对不起,找不到这个姓名\n");
}
else
{
OutputNodeInfo(p);
printf("确认删除? (输入\"y\"确认,任意键取消): ");
if (strcmp(gets(sure), "y") == 0)
{
DeleteNode(p);
printf("删除成功!\n");
SWITCH[6] = 0;
}
fflush(stdin);
}
}
}

/* 输出链表 */
void OutList()
{
Student *p = head->next;

/* 空表处理 */
if (p == NULL)
{
printf("暂无学生信息!\n");
}

while (p != NULL)
{
OutputNodeInfo(p);
p = p->next;
}
}

/* 按姓名查找记录并打印 */
void SearchPrintNode()
{
Student *p = head->next;
int ok = 1;
char name[20];
fflush(stdin);

/* 姓名合法性判断 */
printf("请输入你要查找的学生姓名: ");
do
{
gets(name);

if (!CheckName(name))
{
printf("数据违法,请重新输入姓名: ");
}
}
while (!CheckName(name));

/* 按姓名查找节点 */
while (p != NULL)
{
if (strcmp(p->name, name) == 0)
{
ok = 0;
OutputNodeInfo(p);
}
p = p->next;
}

if (ok)
{
printf("对不起,找不到这个姓名\n");
}
}

/* 计算总分和均分 */
void Compute()
{
int i;
Student *p = head->next;

while (p != NULL)
{
int sum = 0;

for (i = 0; i < CLASS; i++)
{
sum += p->score[i];
}

p->sum = sum;
p->ave = sum * 1.0 / CLASS;
p = p->next;
}
}

/* 比较学号 */
int CmpID(Student* a, Student* b, int k)
{
return strcmp(a->id, b->id);
}

/* 比较总分 */
int CmpSum(Student* a, Student* b, int k)
{
return b->sum - a->sum;
}

/* 比较各科分数 */
int CmpScore(Student* a, Student* b, int k)
{
return b->score[k] - a->score[k];
}

/*

选择最大元素 */
Student* SearchMaxNode(int (*cmp)(Student* a, Student* b, int k), int k)
{
Student *p = head->next;
Student *max = p;

while (p != NULL)
{
if (cmp(p, max, k) < 0)
{
max = p;
}
p = p->next;
}

return max;
}

/* 排序 */
Student* Sort(int (*cmp)(Student* a, Student* b, int k), int k)
{
Student *newhead = MALLOC;
Student *p = newhead;
Student *max;

while (head->next != NULL)
{
max = SearchMaxNode(cmp, k);
p->next = max;
DeleteNode(max);
p = p->next;
}

/* 表尾处理 */
p->next = NULL;
return newhead;
}

/* 输出p指向节点的信息到文件 */
/*FILE结构体定义于stdio.h,如下
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;*/
void OutputToFile(FILE* fp, Student* p, int newline)
{
int i;
fprintf(fp, "%s\n", p->name); /*fprintf:传送格式化输出到一个文件中*/
fprintf(fp, "%s\n", p->id);

for (i = 0; i < CLASS - 1; i++)
{
fprintf(fp, "%d\n", p->score[i]);
}

/* 尾行处理 */
if (newline)
{
fprintf(fp, "%d\n", p->score[i]);
}
else
{
fprintf(fp, "%d", p->score[i]);
}
}

/* 将s插入链表尾部 */
void InsertAfter(Student* s)
{
Student *p = head;

while (p->next != NULL) p = p->next;

s->next = NULL;
p->next = s;
}

/* 保存到文件 */
void SaveToFile()
{
/* 处理追加表尾情况 */
if (SWITCH[12])
{
InsertAfter(tmp);
}

FILE *fp;
char file[20];
fflush(stdin);
printf("请输入文件名: ");
gets(file);

if ((fp = fopen(file, "wt+")) == NULL)
{
printf("对不起,无法创建文件!\n");
return;
}

Student *p = head->next;

while (p != NULL)
{
if (p->next != NULL)
{
OutputToFile(fp, p, 1);
}
else
{
OutputToFile(fp, p, 0);
}

p = p->next;
}

printf("文件保存成功!\n");
fclose(fp);
SWITCH[6] = 1;

/* 处理追加表尾情况 */
if (SWITCH[12])
{
DeleteNode(tmp);
SWITCH[12] = 0;
}
}

/* 从文件中读入记录 */
void LoadFile()
{
int i;
FILE *fp;
char file[20];
fflush(stdin);
printf("请输入文件名: ");
gets(file);

if ((fp = fopen(file, "rt")) == NULL)
{
printf("对不起,无法打开文件!\n");
return;
}

/* 文件未结束时读入数据 */
while (!feof(fp))
{
Student *s = MALLOC;
fscanf(fp, "%s", s->name);
fscanf(fp,

"%s", s->id);

for (i = 0; i < CLASS; i++)
{
fscanf(fp, "%d", &s->score[i]);
}

s->next = head->next;
head->next = s;
}

printf("文件读取成功!\n");
fclose(fp);
}

/* 复制文件 */
void CopyFile()
{
FILE *fp1, *fp2;
char ch, file1[20], file2[20];
fflush(stdin);
/* 读入源文件 */
printf("请输入源文件名: ");
gets(file1);

if ((fp1 = fopen(file1, "rb")) == NULL)
{
printf("对不起,无法打开文件!\n");
return;
}

/* 读入目标文件 */
printf("请输入目标文件名: ");
gets(file2);

if ((strcmp(file1, file2) == 0) || ((fp2 = fopen(file2, "wb")) == NULL))
{
printf("对不起,无法创建文件!\n");
return;
}

/* 逐个字符拷贝 */
while (!feof(fp1)) /*int feof(FILE *stream)功能:检测流上的文件结束符*/
{
ch = fgetc(fp1);

if (ch != EOF) /*stdio内定义宏EOF为-1*/
fputc(ch, fp2);
}

fclose(fp1);
fclose(fp2);
printf("文件拷贝成功!\n");
}

/* 追加记录到文件中 */
void InsertToFile()
{
tmp = MALLOC;
InputNodeInfo(tmp);
SWITCH[12] = 1;
}

/* 分类统计 */
void Stat()
{
int i, j, n = 0;
int sum[CLASS] = {0},jigelv[CLASS]={0},youxiulv[CLASS]={0};
char dengji;
Student *p = head->next;

if (p == NULL)
{
printf("暂无学生信息,无法统计\n");
return;
}

/* 统计各科总分 */
while (p != NULL)
{
/* 记录学生总数 */
n++;

for (i = 0; i < CLASS; i++)
{ /*求各科总成绩*/
sum[i] += p->score[i];
/*求各科及格率、优秀率*/
if(p->score[i] >= 60 && p->score[i] < 80)jigelv[i]++;
if(p->score[i]>=80)youxiulv[i]++;
}

p = p->next;
}


/* 各科分别输出 */
for (i = 0; i < CLASS; i++)
{
printf("%s 总均分: %.2lf\n", CLASSNAME[i], sum[i] * 1.0 / n);
/**/
printf(" 及格率: %.2lf\n",jigelv[i]*1.0/n);
printf(" 优秀率: %.2lf\n",youxiulv[i]*1.0/n);
/**/
head = Sort(CmpScore, i); /*按科目成绩排名*/
j = 0;
p = head->next;

while (p != NULL)
{
j++;
/*划分成绩等级*/
if(p->score[i]>=90)dengji="A";
if(p->score[i]>=80 && p->score[i]<90)dengji="B";
if(p->score[i]>=70 && p->score[i]<80)dengji="C";
if(p->score[i]>=60 && p->score[i]<70)dengji="D";
if(p->score[i]<60)dengji="E";
printf("NO.%d %s %d %c等级\n", j, p->name, p->score[i],dengji);
p = p->next;
}

printf("\n");
}
}

/* 释放链表 */
void FreeList(Student* p)
{
if

(p->next != NULL)
{
FreeList(p->next);
}
free(p);
}

/* 退出 */
void Quit()
{
if (!SWITCH[6])
{
printf("请先保存文件!\n");
return;
}
if (head != NULL)
{
FreeList(head);
}
exit(0);
}



相关文档
相关文档 最新文档