您的位置:首页 > 运维架构 > Linux

Linux环境下C语言实现简单的基于文件的学生信息管理系统

2016-10-30 21:54 1551 查看
一般来说程序运行时的数据都是存储在内存当中的,当程序结束数据也就消失了。在学习了文件操作以后,便想到可以通过读写文件来对数据进行操作,于是尝试编写了一个简单基于文件的学生信息管理系统。

学生信息可以提前按特定的格式存储在文件当中,打开程序后会先对文件进行读操作,将文件中的字符数据保存到程序的链表当中,在程序中可以对链表进行增删改查的操作来管理学生的信息,当结束程序时,会重新将链表中的数据按特定的格式存储到文件当中,这样即使程序结束也可以将数据保存下来,当下一次运行程序时还会重新将数据读取。

下面是具体的实现。

用来存储学生信息的链表,这里只涉及学号和姓名。

typedef struct Student_information
{
char *stu_num;
char *stu_name;
struct Student_information *next;
}S;


将学生信息存储到链表中的函数。

void input_inf(S **head,char *num,char *name)
{
S *tmp = malloc(sizeof(S));
S *find = *head;
char *buf = malloc(20);
char *buf1 = malloc(20);
strcpy(buf,name);
strcpy(buf1,num);

tmp->stu_num = buf1;
tmp->stu_name = buf;
tmp->next = NULL;
if(*head == NULL)
{
*head = tmp;
}
else
{
while(find->next!=NULL)
{
find = find->next;
}
find->next = tmp;
}
}


将文件中学生信息存入链表,返回学生人数。

int read_file(FILE *fp,S **head)
{
int sum=0;
ssize_t len;
size_t l = 0;
char *buf=NULL;
int i=0,j=0;
while((len = getline(&buf,&l,fp))!=-1)
{
char *name=malloc(20);
char *num=malloc(20);
while(*(buf+i)>='0'&&*(buf+i)<='9')
{
*(num+j++) = *(buf+i++);
}
j = 0;
i++;
while(*(buf+i)!='\n')
{
*(name+j++)=*(buf+i++);
}
input_inf(head,num,name);
num = 0;
i = 0;
j = 0;
free(name);
free(buf);
buf = NULL;
l = 0;
sum++;
}
return sum;
}


将链表数据按格式写入文件。

void write_file(FILE *fp,S *head)
{
S *find = head;
if(head==NULL)
return;
while(find->next!=NULL)
{
fputs(find->stu_num,fp);
fputc(' ',fp);
fputs(find->stu_name,fp);
fputc('\n',fp);
find = find->next;
}
fputs(find->stu_num,fp);
fputc(' ',fp);
fputs(find->stu_name,fp);
fputc('\n',fp);
}


显示所有学生信息。

void show_all_inf(S *head)
{
S *find = head;
if(find==NULL)
{
printf("请先输入学生信息!\n");
return;
}
while(find->next!=NULL)
{
printf("Student No.%s\tStudent Name:%s\n",find->stu_num,find->stu_name);
find = find->next;
}
printf("Student No.%s\tStudent Name:%s\n",find->stu_num,find->stu_name);
}


通过学号查找输出学生信息。

void search(S* head,char *num)
{
S *find = head;
while(strcmp(find->stu_num,num)!=0)
{
if(find->next==NULL)
{
printf("未找到该学生!\n");
return;
}
find = find->next;
}
printf("学号No.%s的学生姓名为%s\n",num,find->stu_name);
}


查看链表中是否存在相同学号,存在返回1,不存在返回0。用在添加学生信息时,保证学号为主键。

int if_in(S *head,char *num)
{
S *find = head;
if(head==NULL)
{
return 0;
}
while(strcmp(find->stu_num,num)!=0)
{
if(find->next==NULL)
return 0;
find = find->next;
}
return 1;
}


通过学号删除学生信息。

void del(S **head,char *num,int *sum)
{
S *find = *head;
S *front = NULL;
if(*head == NULL)
{
printf("已无学生信息!\n");
return;
}
while(strcmp(find->stu_num,num)!=0)
{
if(find->next==NULL)
{
printf("该学号不存在!\n");
return;
}
front = find;
find = find->next;
}
printf("学号No.%s的学生姓名为%s\n[1]确认删除 [其他]取消(请勿输入字符!)\n",num,find->stu_name);
int select;
scanf("%d",&select);
if(select==1)
{
if(find==*head)
{
*head = find->next;
find->next = NULL;
free(find);
}
else
{
front->next = find->next;
find->next = NULL;
free(find);
}
*sum--;
printf("删除成功!");
}
}


主函数通过printf和switch实现了简单的界面。这里注意在switch之后需要加一个getchar( ),因为在选择功能时虽然通过scanf输入了一个字符,但实际上还多输入了一个回车,即换行符’\n’,而switch结束后进入下一次循环选择功能时scanf会直接把这个回车符读入进行选择,而不是等待用户的输入,在linux redhat是这样的,所以通过getchar( )来将多余的’\n’读掉。

int main()
{
S *head = NULL;
int sum = 0;
char select = '1';

//读文件信息
FILE *fp = fopen(FILENAME,"r");
if(fp == NULL)
{
printf("数据库错误!");
exit(EXIT_FAILURE);
}
sum = read_file(fp,&head);
fclose(fp);
system("clear");

//主程序功能部分
while(select!='q')
{
char *name = malloc(20);
char *num = malloc(20);
char *search_num = malloc(20);
printf("***  Student Manage System  ***\n");
printf("***  [1] 添加学生信息       ***\n");
printf("***  [2] 列出所有学生信息   ***\n");
printf("***  [3] 查询学生信息       ***\n");
printf("***  [4] 学生总数查询       ***\n");
printf("***  [5] 删除学生信息       ***\n");
printf("***  [q] 退出               ***\n");
printf("请选择:");
scanf("%c",&select);
switch(select)
{
case '1':
printf("学生学号:");
scanf("%s",num);
printf("学生姓名:");
scanf("%s",name);
printf("您要添加的学生学号为No.%s,姓名为%s\n",num,name);
printf("*** [1] 确认添加 [其他]取消(请勿输入字符!)\n");
printf("请选择:");
int chose = 0;
scanf("%d",&chose);
if(chose==1)
{
if(if_in(head,num))
{
printf("学号已存在!请重新输入!\n");
}
else
{
input_inf(&head,num,name);
sum++;
printf("添加成功!\n");
}
}
else
{
printf("已取消!\n");
}
printf("---  3s后返回主页面  ---\n");
sleep(3);
system("clear");
break;

case '2':
show_all_inf(head);
printf("---  3s后返回主页面  ---\n");
sleep(3);
system("clear");
break;
case '3':
printf("输入学生学号:");
scanf("%s",search_num);
search(head,search_num);
printf("---  3s后返回主页面  ---\n");
sleep(3);
system("clear");
break;
case 'q':
break;
default:
printf("请重新选择!\n");
select = '1';
search(head,search_num);
printf("---  3s后返回主页面  ---\n");
sleep(3);
system("clear");
break;

case '4':
printf("学生总数为%d人。\n",sum);
printf("---  3s后返回主页面  ---\n");
sleep(3);
system("clear");
break;

case '5':
printf("输入要删除学生的学号:");
scanf("%s",search_num);
del(&head,search_num,&sum);
printf("---  3s后返回主页面  ---\n");
sleep(3);
system("clear");
break;
}
getchar();//这个getchar非常重要!用来读掉回车符!
}
FILE *fw = fopen(FILENAME,"w+");
write_file(fw,head);

return 0;
}


以下是需要的头文件

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define FILENAME "Stu_data"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: