学生成绩的存储与查询
题目
我们首先得知道在一个项目里可以写很多个程序,但只能有一个主函数
解题:
首先创建一个项目
Devc++会自动生成一个main.c
主函数题目已经提供直接放进去
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include<string.h>
#include "student.h"
int main()
{
Student* stus;
char path[1024];
int N;
getcwd(path,1024);
strcat(path,"\\data.txt");
//输入学生人数
printf("学生人数N=");
scanf("%d",&N);
//创建动态结构体数组
stus=(Student*)malloc(sizeof(Student)*N);
//输入各学生学号,姓名,某门课平时、考试成绩(这些字段的值之间用英
//文逗号隔开),总评成绩根据平时、考试分别占0.2,0.8比例自动计算
//输入完一个学生后,回车即可输入下一个学生信息
inputInformation(stus,N);
//把学生成绩记录存入文件,存入文件后关闭文件
saveInformation(stus,N,path);
//释放内存
free(stus);
//从文件中读取学生成绩记录,输出最低、最高总评成绩对应的学生完整信息
printf("全部学生、总评最低和最高学生信息如下:\n");
outputInformation(path);
return 0;
}
在添加一个
点击项目,点击添加
并名名为student.h,题目有个坑给你head.h,我最开始就写的这个
#ifndef STUDENT_H_INCLUDED//防止重复定义
#define STUDENT_H_INCLUDED
typedef struct student
{
char stu_number[20];
char stu_name[20];
float usual_mark;
float exam_mark;
float overall_mark;
}Student;
void inputInformation(Student*stus,int N);
void saveInformation(Student*stus,int N,char*filename);
void outputInformation(char*filename);
#endif
这里有个知识点
#ifndef STUDENT_H_INCLUDED//防止重复定义
#define STUDENT_H_INCLUDED
#endif
我们知道函数的定义不能重复,如果我写了这个函数,并存放在这个.h的文件中,我写另外一个.h文件时,又要用到它,这时就会造成定义重复问题,所以变产生上面这种写法
翻译:
如果没定义Student.h
就定义Student.h
如果定义了
就不再定义
最后时student.c
注释都在代码里了
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#include "student.h"
//请在下面给出程序中所用到的自定义函数的完整定义
//打开文件的标准代码 FILE*fp=fopen("file","r");
/*FILE*fp=fopen("file","r");
if(fp)
{
fscanf(fp,...);
fclose(fp);
}
else{
}**/
void inputInformation(Student*stus,int N)//根据意思很好理解就是写入数据 Student*stus 就是数组结构Student stus[]
{//这个函数还是比较简单的
int i;
for(i=0;i<N;i++)//
{
printf("学生%d的学号,姓名,平时成绩,考试成绩(空格分隔):\n",i);
scanf("%s",(stus+i)->stu_number);//这里用%s,注意看我们定义的机构中stu_number是数组
scanf("%s",(stus+i)->stu_name);
scanf("%f",&(stus+i)->usual_mark);
scanf("%f",&(stus+i)-> exam_mark);
(stus+i)->overall_mark=0.2*(stus+i)->usual_mark+0.8*(stus+i)->exam_mark;
}
}
void saveInformation(Student*stus,int N,char*filename)//main函数中,我们将path里面装个一个文本data.txt
{//现在我们要数据放入文件中储蓄起来
int i;
FILE*pf=NULL;//C语言中w与wb. w:打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。.
//若文件不存在则建立该文件。. wb:只写方式打开或新建一个二进制文件,只允许写数据。
pf=fopen(filename,"wb");
for(i=0;i<N;i++)
{
fprintf(pf,"%s %s %f %f %f\n",(stus+i)->stu_number,(stus+i)->stu_name,(stus+i)->usual_mark,(stus+i)-> exam_mark,(stus+i)->overall_mark);
}// int fprintf(FILE *stream, const char *format, ...) 发送格式化输出到流 stream 中
fclose(pf);
pf=NULL;
}
void outputInformation(char*filename)//输出文本中的内容,并且比较大小
{
int i=0;
Student*stus=(Student*)malloc(sizeof(Student)*10);//给10个空间就够了
FILE*pf=fopen(filename,"rb");//rb代表打开一个已有的二进制文件,允许读取文件
printf("全部学生:\n");
fscanf(pf,"%s %s %f %f %f",stus->stu_number,stus->stu_name,&stus->usual_mark,&stus->exam_mark,&stus->overall_mark);
/*fscanf 函数原型为 int fscanf(FILE * stream, const char * format, [argument...]); 其功能为根据数据格式(format),
从输入流(stream)中读入数据,存储到argument中,遇到空格和换行时结束。fscanf位于C标准库头文件<stdio.h>中。
*/
while(!feof(pf))// feof()是检测流上的文件结束符的函数,如果文件结束,则返回非0值,否则返回0
//一般在文件操作,中经常使用feof()判断文件是否结束。
//题目说了该文件还能读取所以要这么写
{
i++;
fscanf(pf,"%s %s %f %f %f",(stus+i)->stu_number,(stus+i)->stu_name,&(stus+i)->usual_mark,&(stus+i)-> exam_mark,&(stus+i)->overall_mark);//根据题目的意思除了能存储数据
}
int k;
for(k=0;k<i;k++)
{
printf("学号=%s,姓名=%s,平时成绩=%.2f,考试成绩=%.2f,总评成绩=%.2f\n",(stus+k)->stu_number,(stus+k)->stu_name,(stus+k)->usual_mark,(stus+k)-> exam_mark,(stus+k)->overall_mark);
}
fclose(pf);
pf=NULL;
//最后用以前学习的方法进行比较大小
//这里换成了结构之间的比较
float min= (stus+0)->overall_mark;
float max= (stus+0)->overall_mark;
Student*Max=(stus+0);
Student*Min=(stus+0);
for(k=1;k<i;k++)
{
if(min>(stus+k)->overall_mark)
{
min=(stus+k)->overall_mark;
Min=(stus+k);
}
}
printf("最低分学生:\n");
printf("学号=%s,姓名=%s,平时成绩=%.2f,考试成绩=%.2f,总评成绩=%.2f\n",Min->stu_number,Min->stu_name,Min->usual_mark,Min->exam_mark,Min->overall_mark);
for(k=1;k<i;k++)
{
if(max<(stus+k)->overall_mark)
{
max=(stus+k)->overall_mark;
Max=(stus+k);
}
}
printf("最高分学生:\n");
printf("学号=%s,姓名=%s,平时成绩=%.2f,考试成绩=%.2f,总评成绩=%.2f",Max->stu_number,Max->stu_name,Max->usual_mark,Max->exam_mark,Max->overall_mark);
}
运行结果
遇到的问题
首先写完这个函数的时候我的就写了一排
问题在哪里?
对什么时候取地址符搞混了
fprintf
fscanf
这两函数是不一样
以及printf
以及用完这个文件
记得关闭这个空间
也就是最后pf=NULL
错误的运行
最后,最后
一定注意平台的编译器,对空格,对换黄,对符号是英文还是中文很敏感细心点!!