功能分析(需求):分析软件用户的需求,以及需要分析统计的数据。
模块划分(设计):基于功能划分、基于层次划分、基于专业划分、基于需求划分,通过功能分析,对系统所需要的功能进行划分,首先将规模较大的问题分解为若干个功能相对独立的小问题即模块,每个模块还可以再细分,这个过程也可参照自顶向下、逐步求精的思路完成。根据上述的需求分析确定系统应该完成的几大功能模块。
关键技术研究(设计与编码的过渡):通过功能分析和模块划分,了解实现该系统功能需要的关键技术。
代码实现(编码):书写程序代码。
测试:运行系统,测试系统。
基于用户的需求分析:
(1)管理员用户:教师和学生信息管理。
(2)教师用户: 成绩管理。
(3)学生用户: 成绩查询。
(1)学生数据(结构体)
(2)用户数据(结构体)
问题求解过程中,要有效地表示和组织问题相关的数据,包括输入、输出、中间结果等,在设计算法时,需要精确定义对何种对象进行操作,可以进行哪些操作等,这些必须在开始编写代码之前完成。本系统中约定学生的信息需要包括学号、姓名、3门课的成绩和总分,学生的数据信息存放在磁盘文件中。
1、管理员:增删改用户。
2、教师:增删改成绩(成绩管理)、查询成绩(成绩、学号、课程)、成绩统计(平均分、排序)、成绩输出。
3、学生:查询成绩(姓名、学号、课程)。
学生信息、用户信息。
用户的每个功能使用函数实现。
用户信息和学生成绩信息。
(1)学生类型
(2)用户类型
(1)先定义结构体类型,再定义结构体变量。
struct student
{ char name[20];
char num[12];
int score[M+1];
};
struct student stu1,stu2;
(2)在定义结构体类型的同时说明结构体变量。
(3)省略结构体类型名,直接定义结构体变量。
引用:结构体变量名.成员名
赋值:逐个成员赋值、整体赋值
gets(stu1.name); gets(stu1.num);
stu1.score[M]=0;
for(i=0;i
struct student
{ char name[20];
char num[12];
int score[M+1];
}stu[1000];
for(i=0;i<1000;i++)
{gets(stu[i].name);
gets(stu[i].num);
for(j=0;j
struct student *pstu,stu1; pstu=&stu1;
pstu->num (*pstu).num
*pstu=stu;
gets((*p).name);或者gets(p->name);
void students()
{int sel;
char filename[20];
do
{ printf("------------学生模块的选择-------------\n");
printf("---------------------------------------\n");
printf(" 1: 按姓名查询 \n");
printf(" 2: 按学号查询 \n");
printf(" 3: 按课程查询 \n");
printf(" 0: 退出 \n");
printf(" 请选择 0-3 \n");
printf("----------------------------------------\n");
scanf("%d",&sel);getchar();
switch(sel)
{ case 1: printf("请输入学生姓名");gets(name);quname(name);break;
case 2: printf("请输入学生学号");gets(name); qunum(name);break;
case 3: qusub();break;
case 0: return;
}
}while(1);
}
函数名(实参表列)
类型标识符 函数名(形参表列)
定义文件指针-》打开文件-》读写文件-》关闭文件
1、文件指针
FILE *fp1;
typedef struct
{ short level; /* fill/empty level of buffer */
unsigned flags; /* File status flags */
char fd; /* File descriptor */
unsigned char hold; /* Ungetc char if no buffer */
short bsize; /* Buffer size */
unsigned char *buffer; /* Data transfer buffer */
unsigned char *curp; /* Current active pointer */
unsigned istemp; /* Temporary file indicator */
short token; /* Used for validity checking */
} FILE;
FILE *文件指针名;
fopen("文件名","打开模式");
if((fp=fopen("e:\\usdata1.txt","w"))==NULL)
{printf("不能打开文件\n");
exit(0);
}
使用文件方式见下表:
fclose(文件指针)
fclose(fp);
(1)、输入/输出字符
键盘依次输入一些字符,并将他们逐个存储到磁盘文件data1.txt中去,直到输入的字符为'$'为止。
if((fp=fopen("data1.txt","w"))==NULL)
{ printf("cann't open data1.txt\n");
exit(0); }
ch=getchar();
while(ch!= '$')
{ fputc(ch,fp);
ch=getchar(); }
fclose(fp);
(2)输入/输出字符串
从dt6.txt文件中一次读取5个字符,并将之与字符数组cmpstr的内容比较,若两者不同,则将读取的字符存储到dt7.txt的结尾处,直到dt6.txt结束。
if((fp1=fopen("dt6.txt","r"))==NULL)
{ printf("Can't open dt6.txt!\n"); exit(0); }
if((fp2=fopen("dt7.txt","a"))==NULL)
{ printf("Can't open dt7.txt!\n"); exit(0); }
gets(cmpstr);
fgets(filestr,6,fp1);
while(!feof(fp1))
{if(strcmp(filestr,cmpstr)!=0) fputs(filestr,fp2);
fgets(filestr,6,fp1);
}
fclose(fp1); fclose(fp2);
【例2-1】编写函数,验证输入的用户名、密码和类别是否正确,相关信息存放在磁盘文件E:\usdata1.txt中。
(3)格式化输入/输出
①定义字符数组fname和fpass、文件类型的指针fp、整型变量found,fclas;
②found=0;
③以读的方式打开磁盘文件e:\usdata1.txt,fp指向打开的文件;如果fp=NULL,结束;
④当文件没有结束的时候做循环:
⑤关闭文件
⑥return found
Check函数的具体代码如下:
int check(char na[],char pa[],int cl)
{
char fname[20];
char fpass[10];
FILE *fp;
int found=0,fclas;
if((fp=fopen("e:\\usdata1.txt","r"))==NULL)
{printf("不能打开文件\n");
exit(0);
}
while(!feof(fp))
{ fscanf(fp,"%s %s %d",fname,fpass,&fclas);
if(strcmp(fname,na)==0&&strcmp(fpass,pa)==0 && fclas==cl)
{found=1;break;}
}
fclose(fp);
return found;
}
【例2-2】编写一个函数input(),将一批学生的数据存放到磁盘文件"E:\stu_in.dat"中,每个学生的信息包括姓名、学号和3门课的成绩。输入“end”表示全部有效数据输入完成。
#include "stdio.h"
#include "string.h"
#define M 3
int n;/*成绩文件中有n条数据*/
struct student
{ char name[20];
char num[12];
int score[M+1];
}stu[1000];
void input() /*输入姓名、学号和成绩,添加到文件中*/
{ FILE *fp;
char filename[20]="E:\\stu_in.dat";
int i,j;
printf("输入姓名、学号和%d门成绩,输入“end”结束\n",M);
i=0;
gets(stu[i].name);
gets(stu[i].num);
for(j=0;j
(1)fseek函数
fseek(文件指针,偏移量,起始位置);
fseek(fp,100L,0);将位置指针移到离文件头100个字节处。
fseek(fp,50L,1); 将位置指针移到离当前位置50个字节处。
fseek(fp,-10L,2);将位置指针从文件末尾处向后退10个字节。
例:磁盘文件上存有10个学生的数据,要求将第1,3,5,7,9个学生数据输入计算机,并在屏幕上显示出来。
if((fp=fopen("stu_list","rb"))==NULL)
{ printf("cannot open file\n"); exit(0); }
for(i=1;i<11;i+=2)
{fread(&stud[i],sizeof(struct student_type),1,fp);
printf("%s %d %d\n",stud[i].name,stud[i].num,stud[i].age);
fseek(fp,i*sizeof(struct student_type),0);
}
fclose(fp);
(2)rewind函数:返回文件开头
rewind(文件指针);
(3)ftell函数:得到文件当前位置
ftell(文件指针);
void main()
{ int sel,fclas,found;
char username[20],password[10];
printf("--------学生成绩管理系统登录---------\n");
printf("-------------------------------------\n");
printf(" 1: 管理员 \n");
printf(" 2: 教师 \n");
printf(" 3: 学生 \n");
printf(" 0: 退出 \n");
printf("-------------------------------------\n");
while(1)
{ printf(" 请输入 0-3 \n");
scanf("%d",&sel);getchar(); /*抵消输入数据后的回车*/
if(sel!=0)
{
printf("请输入用户名");
gets(username);
printf("请输入密码");
gets(password);
if(check(username,password,sel)==0) /*调用check函数判断用户信息是否正确*/
{printf("用户名或密码或类别不对\n");}
else
switch (sel)
{
case 1: printf("欢迎%s管理员\n",username);yhgl();break;
case 2: printf("欢迎%s老师\n",username);teacher();break;
case 3: printf("欢迎%s同学\n",username);students(username);break;
}
}
else
exit(0);
}
}
int check(char na[],char pa[],int cl)
{
char fname[20];
char fpass[10];
FILE *fp;
int found=0,fclas;
if((fp=fopen("e:\\usdata1.txt","r"))==NULL)
{printf("不能打开文件\n");
exit(0);
}
while(!feof(fp))
{ fscanf(fp,"%s %s %d",fname,fpass,&fclas);
if(strcmp(fname,na)==0&&strcmp(fpass,pa)==0 && fclas==cl)
{found=1;break;}
}
fclose(fp);
return found;
}
void yhgl()
{ int sele;
char username[20];
char password[10];
printf("--------用户管理-----------\n");
printf("---------------------------\n");
printf(" 1: 添加用户 \n");
printf(" 2: 删除用户 \n");
printf(" 3: 修改用户 \n");
printf(" 0: 退出 \n");
printf("---------------------------\n");
do
{
printf(" 请输入 0-3 \n");
scanf("%d",&sele);
switch(sele)
{case 1: printf("输入添加的用户信息\n");add();break;
case 2: printf("输入要删除的用户信息\n");del();break;
case 3: printf("输入要修改的用户信息\n");edits();break;
case 0: exit(0);
default: printf("请输入0~3\n");
}
}while(1);
}
void add()
{
char usname[20];
char uspw[10];
int clas;
FILE *fp;
if((fp=fopen("e:\\usdata1.txt","a"))==NULL) /*打开文件的方式用"a"表示追加,在原文件尾部继续写数据。*/
{printf("不能打开文件\n");
exit(0);
}
printf("请输入用户名、密码和类别");
gets(usname);
gets(uspw);
scanf("%d",&clas);
getchar();
fprintf(fp,"%s %s %d\n",usname,uspw,clas);
fclose(fp);
}
void del(char name[])
{struct yh
{char name[20];
char pass[10];
int f;
}std1[100];
FILE *fp;
int i=0,n;
if((fp=fopen("e:\\usdata1.txt","r"))==NULL)
{printf("不能打开文件\n");
exit(0);
}
while(!feof(fp))
{fscanf(fp,"%s %s %d",std1[i].name,std1[i].pass,&std1[i].f);
if (strcmp(name,std1[i].name)!=0) i++;
}
fclose(fp);
if((fp=fopen("e:\\usdata1.txt","w"))==NULL)
{printf("不能打开文件\n");
exit(0);
}
for(n=0;n
void edits(char nam[])
{struct yh
{char name[20];
char pass[10];
int f;
}std1[100];
FILE *fp;
int i=0,n,lb;
char yhm[20],pw[10];
printf("输入修改后的用户名、密码和类别");
gets(yhm);
gets(pw);
scanf("%d",&lb);
if((fp=fopen("e:\\usdata1.txt","r"))==NULL)
{printf("不能打开文件\n");
exit(0);
}
while(!feof(fp))
{fscanf(fp,"%s %s %d",std1[i].name,std1[i].pass,&std1[i].f);
if (strcmp(nam,std1[i].name)==0)
{strcpy(std1[i].name,yhm);strcpy(std1[i].pass,pw);std1[i].f=lb;}
i++;
}
fclose(fp);
if((fp=fopen("e:\\usdata1.txt","w"))==NULL)
{printf("不能打开文件\n");
exit(0);
}
for(n=0;n
void teacher()
{int sel;
char filename[]="E:\\stu_in.dat";
do
{ printf("------------教师模块的选择-------------\n");
printf("---------------------------------------\n");
printf(" 1: 成绩管理 \n");
printf(" 2: 成绩查询 \n");
printf(" 3: 成绩统计 \n");
printf(" 4: 成绩输出 \n");
printf(" 0: 退出 \n");
printf(" 请选择 0-4 \n");
printf("----------------------------------------\n");
scanf("%d",&sel);getchar();
switch(sel)
{ case 1: addsc();break;
case 2: query();break;
case 3: calc();break;
case 4: print(filename);break;
case 0: exit(0);
}
}while(1);
}
void addsc() /*输入姓名、学号和成绩,添加到文件中*/
{ FILE *fp;
char filename[20]="E:\\stu_in.dat";
int i,j;
printf("输入姓名、学号和%d门成绩,输入“end 1 1 1 1”结束\n",M);
i=0;
gets(stu[i].name);
gets(stu[i].num);
for(j=0;j
void print(char *fn)/*输出全部数据,数据信息存放在fn指向的文件中*/
{ FILE *fp;
int i=0,j;
if((fp=fopen(fn,"rb"))==NULL)
{printf("cann't open the file");
exit(0);
}
while(!feof(fp))
fread(&stu[i++],sizeof(struct student),1,fp);
fclose(fp);
n=i;
for(i=0;i
void qunum(char nam[])/*根据学号查找成绩*/
{ FILE *fp;
int i,j;
if((fp=fopen("E:\\stu_in.dat ","rb"))==NULL)
{printf("cann't open stu_in.dat");
exit(0);
}
i=0;
do{
fread(&stu[i],sizeof(struct student),1,fp);
if(strcmp(nam,stu[i].num)==0)
{ puts(stu[i].name);
puts(stu[i].num);
for(j=0;j
void qufail()/*查询不及格的学生*/
{ FILE *fp,*fp2;
int i=0,j,k,l=0;
if((fp=fopen("E:\\stu_in.dat","rb"))==NULL)
{printf("cann't open the file");
exit(0);
}
if((fp2=fopen("E:\\stufail.dat","wb"))==NULL)
{printf("cann't open the file");
exit(0);
}
while(!feof(fp))
fread(&stu[i++],sizeof(struct student),1,fp);
fclose(fp);
n=i;
for(i=0;i
void calc()/*计算每个学生的总分,放到stutotal.txt中*/
{ FILE *fp1,*fp2;
struct student stu1;
char bt[6][10];
int i=0,j,k,l=0;
if((fp1=fopen("E:\\stu_in.dat","rb"))==NULL)
{printf("cann't open the file");
exit(0);
}
if((fp2=fopen("E:\\stutotal.txt","w"))==NULL)
{printf("cann't open the file");
exit(0);
}
while(!feof(fp1))
fread(&stu[i++],sizeof(struct student),1,fp1);
fclose(fp1);
n=i;
fprintf(fp2,"\n%10s%10s%5s%5s%5s%5s\n","姓名","学号","数学","语文","英语","总分");
for(i=0;i
void students()
{int sel;
char filename[20];
do
{ printf("------------学生模块的选择-------------\n");
printf("---------------------------------------\n");
printf(" 1: 按姓名查询 \n");
printf(" 2: 按学号查询 \n");
printf(" 3: 按课程查询 \n");
printf(" 0: 退出 \n");
printf(" 请选择 0-3 \n");
printf("----------------------------------------\n");
scanf("%d",&sel);getchar();
switch(sel)
{ case 1: printf("请输入学生姓名");gets(name);quname(name);break;
case 2: printf("请输入学生学号");gets(name); qunum(name);break;
case 3: qusub();break;
case 0: return;
}
}while(1);
}
void quname(char nam[])/*根据姓名查找成绩*/
{FILE *fp;
int i,j;
if((fp=fopen("E:\\stu_in.dat ","rb"))==NULL)
{printf("cann't open stu_in.dat");
exit(0);
}
i=0;
do{
fread(&stu[i],sizeof(struct student),1,fp);
if(strcmp(nam,stu[i].name)==0)
{ puts(stu[i].name);
puts(stu[i].num);
for(j=0;j