桓楠百科网

编程知识、经典语录与百科知识分享平台

C语言入门:利用文件实现有保存功能的学生成绩管理程序

学生成绩管理程序主菜单写出了该程序具备的功能:

一、最初的没有文件读写功能的学生成绩管理程序

我们最初的程序,实现了学生信息的增、删、改、查和打印功能,并没有文件读写功能。程序如下。

程序1:

我们昨天将学生成绩管理程序的保存功能加上了,就是说我们输入的学生信息在程序结束之前都保存到一个文件里了。

二、增加了保存文件(写文件)功能的学生成绩管理程序

我们将昨天讲的写文件的函数saveFile( )加进上述代码,即将程序1的第2部分的代码改成如下形式:

此时读文件的函数readFlie( )还没有写。

程序1的第3部分,在主函数中增加一行代码:saveFlie(a); 调用saveFile( )保存我们从键盘输入的学生信息(即数组变量a的所有元素)。

我们运行这个程序时,可以将从键盘输入的学生信息保存到文件Student.txt中。

但是当我们再次运行程序时,发现数据还是空的,为什么呢?因为我们没有把文件里的学生信息读到程序中。

今天我们把这个功能加上。

三、如何将文件的内容读出来并保存到程序的变量中?

我们先看文件Student.txt文件里面有什么信息。

文件Student.txt每一行是一个学生的信息:学号、姓名和成绩,我们要读出这个文件的内容,怎么实现呢?

先写一个读文件的简单验证程序,单纯实现读出文件的内容。

程序2:读出文件Student.txt的内容。

number是全局变量,存放学生总人数,虽然在程序2中用不到number,但是每读出文件一行信息,number就加1。

循环体中有4句:

第1句:文件输入函数fscanf( )把文件内容读出来给数组a;

第2句:每读出一行信息就让number加1,即学生总人数加1;

第3句:标准输出函数printf( )把这行信息显示出来让我们看;

第4句:i加1,即数组下标加1。

如果把函数readFile( )加到学生成绩管理程序中的时候,是不需要每读出一行信息就用printf函数把这行信息输出到显示器上,这里是为了验证,所以加了这行输出信息到显示器上的代码:

程序1运行结果:

如果我们把文件Student.txt删掉,现在这个文件Student.txt不存在,那么程序1是否还能正常运行呢?

此时程序运行结果为:

出现乱码,不对了。

我们看看是什么原因?

这是因为:

当文件不存在时,输出“文件不存在!”,然后后面有执行while(!feof(fp)),文件都不存在了还要fscanf()读信息,当然会出现乱码啦。

怎么改呢?

在if后面要加else,这个else写在while(!feof(fp))前面。代码如下:

当文件不存在时,程序1运行结果为:

显示“文件不存在!”后程序就结束了,不会出现乱码。

四、完整的学生成绩管理程序:增加了保存文件(写文件)和读文件的功能

现在我们把函数readFile( )添加到学生成绩管理程序中,在程序运行一开始就调用readFile( )把文件的内容读出到数组变量a中,此时我们把readFlie( )中的输出语句:

删掉了,这里只是读出数据赋值给数组变量a,不需要输出。

程序1的第2部分改为:

程序1的第3部分主函数中,在运行开始就调用函数readFlie( ),读出文件内容到数组变量a中,在程序准备结束时调用函数saveFile( ) 将数组变量a中所有元素写到文件中保存。

第一次运行程序,若文件Student.txt不存在,则先显示“文件不存咋!”以后再出现主菜单。

以下是完整程序代码,可以直接复制运行。

//********************程序开始************************//

#include <stdio.h>

//第1部分:定义结构类型、全局变量

struct STUD

{ int xh; // 学号

char name[20]; // 姓名

int cj; // 成绩

};

int number=0; // 全局变量,学生总数

//第2部分:函数原型声明

void f1(struct STUD a[]);

void f2(struct STUD a[]);

void f3(struct STUD a[]);

int f4(struct STUD a[]);

void f5(struct STUD a[]);

void saveFile(struct STUD a[]);//写文件

void readFile(struct STUD a[]);//读文件

void saveFile(struct STUD a[])

{ FILE *fp;

int i;

fp=fopen("Student.txt","w"); //打开方式 w, 清空原有内容,全部重写

for(i=0;i<number;i++) //共有number名学生

{

fprintf(fp,"%d %s %d\n", a[i].xh, a[i].name, a[i].cj);

}

fclose(fp);

}

void readFile(struct STUD a[])

{ FILE *fp;

int i=0; //循环变量

fp=fopen("Student.txt","r"); //打开方式 r, 读文件

if((fp=fopen("Student.txt","r")) == NULL)

{

printf("文件不存在!\n");

}

else

{

while(!feof(fp))

{ fscanf(fp,"%d %s %d\n", &a[i].xh, a[i].name, &a[i].cj);

number++; //学生人数加1

// printf("%d %s %d\n", a[i].xh, a[i].name, a[i].cj);

i++;

}

}

fclose(fp);

}

//第3部分 主函数

int main( )

{ struct STUD a[100]; int xz, f=1;

readFile(a); //调用读文件函数,读出文件内容到数组a中


while(f==1)

{ printf("\n********************\n");

printf(" *1 增加 *\n *2 删除 *\n");

printf(" *3 修改 *\n *4 查询 *\n");

printf(" *5 打印 *\n *0 退出 *\n");

printf("********************\n");

printf("请选择:");

scanf("%d", &xz);

switch(xz)

{ case 1: f1(a); break;

case 2: f2(a); break;

case 3: f3(a); break;

case 4: f4(a); break;

case 5: f5(a); break;

case 0: f=0; break;

}

}


saveFile(a); //调用写文件函数,保存数组a所有元素


return 0;

}

//第4部分 增加学生信息的函数f1

void f1(struct STUD a[]) //增加

{

int n, i;

printf("您需要增加多少个学生记录:");

scanf("%d", &n);

for(i=number;i<number+n;i++)

{

printf("请输入学号:");

scanf("%d", &a[i].xh);

printf("请输入姓名:");

scanf("%s", a[i].name);

printf("请输入成绩:");

scanf("%d", &a[i].cj);

}

number=number+n;

printf("添加成功\n");

}

//第5部分 查询学生信息的函数f4

int f4(struct STUD a[]) //查询

{

int flag; int i,x; int xz;

printf("\n请输入要修改的学号:");

scanf("%d",&x);

for(i=0;i<number;i++)

{

if(a[i].xh==x)

{

printf("找到学号为%d的学生,该生信息如下:\n",x) ;

printf("%d %s %d \n", a[i].xh,a[i].name,a[i].cj);

flag=i;

break;

}

}

if(i>=number)

{

printf("查无此人\n");

flag=-1;

}

return flag;

}

//第6部分 删除学生信息的函数f2

void f2(struct STUD a[]) //删除

{

int d=f4(a); //先调用f4查找有没有这个学生

if(d==-1)

printf(" 查无此人,无法删除\n");

else

{

a[d].xh=-1; //直接将学号改成-1

printf("删除成功\n");

}

}

//第7部分 修改学生信息的函数f3

void f3(struct STUD a[]) //修改

{

int d=f4(a); //先调用f4查找有没有这个学生

if(d==-1)

printf(" 查无此人,无法修改\n");

else

{

printf("请输入新的学号、姓名、成绩:\n");

scanf("%d%s%d",&a[d].xh,a[d].name,&a[d].cj);

printf("修改成功\n");

}

}

//第8部分 打印所有学生信息

void f5(struct STUD a[]) //打印

{

int xz, flag=1, i;

struct STUD max;

for(i=0;i<number;i++)

{

if( a[i].xh != -1 ) //把学号不等于-1的信息删除

printf("%d %s %d\n",a[i].xh,a[i].name,a[i].cj);

}

}

//********************程序结束************************//

至此我们完成了一个具有增删改查及保存功能的学生成绩管理程序。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言