Created
July 14, 2013 17:59
-
-
Save yuikns/5995108 to your computer and use it in GitHub Desktop.
感觉博主代码还有些改进的地方,所以手痒改了一番.gcc编译测试通过.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
// 硬编码就不说什么了,不过真的环境中随意使用硬编码绝对是不可取的 | |
#define N 208 | |
// 命名规则习惯,你这儿说的是1个student,请不要加s | |
typedef struct | |
{ | |
long stu_id; //学号 | |
char name[20]; //学生姓名 | |
int class_id; //班级号 | |
char profession[20]; //专业名称 | |
// 这儿这个结构我觉得做的不怎么合理,稍稍修改 | |
//int average_sucess; //个人专业平均成绩 | |
//int science; //科技活动奖励加分 | |
//int ociology; //社会活动奖励加分 | |
//int pro_flag; //专业挂科记录 | |
//int CET4_flag; //英文四级是否通过 | |
int scores[3]; // 0: 个人专业平均成绩 1: 科技活动奖励加分 2:社会活动奖励加分 | |
int flags; // 按位保存bool flag 从低到高分别保存: 1.专业挂科记录 2.CET4是否过 共可以保存int类型位数个 | |
//文中没有保研方面相关信息,勿凭空生成 | |
//int status; //保研状况 | |
double average; // scores[0] * 0.6 + scores[1] * 0.3 + scores[2] * 0.1 | |
}student; | |
typedef student * p_student ; // 我们可以这么用typedef | |
// 全局变量谨慎使用 | |
int comp(const void *lp,const void *rp) | |
{ | |
return ((p_student)rp)->average > ((p_student)lp)->average; // | |
} | |
//读取文本文件,最好不要凭空来个文件名 | |
int fun_load(const char * file_name,p_student p,int max_len); | |
void fun_sort(p_student ,int len);//排序计算排名 为毛注释是"冒泡"?说好的qsort呢 | |
void fun_print_all(p_student p,int len);//输出所有学生表单 | |
// 很好,我喜欢你没有写 void main | |
int main(int argc, char *argv[]) | |
{ | |
// 其实可以用malloc或calloc,但是既然没有用,我也不用了 | |
student data[N]; //申请空间,以后的操作都在这儿搞 | |
p_student ps; | |
ps = data; // 等价于 ps = &data[0]; | |
// i是什么意思 ? 我们用个更加容易理解的变量名吧 | |
int num=fun_load("stud.txt",ps,N); //读取文本内容 得到学生信息总数 | |
if(num == 0) | |
{ | |
fprintf(stderr,"读取信息为空!\n"); | |
return -1; // 在main中,返回0表示正常,返回非0表示不同的错误,以便调试之类 | |
} | |
fun_sort(ps,num); //全校排名 | |
fun_print_all(ps,num); //输出 | |
return 0; | |
} | |
//将文本文件内容读取到结构体数组中 | |
int fun_load(const char * file_name,p_student p,int max_len) | |
{ | |
int num=0; | |
FILE *fp; | |
if((fp=fopen(file_name,"r"))==NULL) | |
{ | |
fprintf(stderr,"无法打开指定文件\n"); | |
// 错误信息我们输出到 stderr,正常进程信息我们输出到stdout | |
//不要直接断开,我们不妨返回"找到0个内容"吧 | |
return 0; | |
} | |
// 我们观察目标文件,每条信息放在一行,中间用\t隔开 | |
// 读取文件有很多方法,比如fread/fwrite比较适用于读取固定长度的文件 | |
// 此处比较适合按行读取 | |
// linux C 提供了getline,但是它不是std函数 | |
// std库只提供了fgets | |
// fgets的原型是: char *fgets(char *s, int size, FILE *stream); | |
// 此外,我们传入参数有个 max_len,表示已申请的空间的容量, | |
// 用来保证没有下标越界的问题 | |
// 所以我们读取的是"小于等于N条数据",而不是所有数据 | |
char buff[1024]; | |
const char *delim = "\t"; // 分隔符定义为 \t | |
while(fgets(buff,1024,fp) != 0 && num < max_len) | |
{ | |
// 字符串数组初始化 | |
memset(p[num].name,0,20); | |
memset(p[num].profession,0,20); | |
// strtok 是一种分割字符串的很好的方法,注意:线程不安全 | |
p[num].stu_id = atol(strtok(buff,delim)) ; // | |
// memcpy 是最好的字符串copy , 20表示最长copy 19个字符, | |
// 因为至少要一个位置存放'\0'表示结束 | |
memcpy(p[num].name,strtok(NULL,delim),19); | |
p[num].class_id = atoi(strtok(NULL,delim)) ; // | |
memcpy(p[num].profession,strtok(NULL,delim),19); | |
int j; | |
for(j=0;j<3;j++) | |
p[num].scores[j] = atoi(strtok(NULL,delim)) ; // | |
int pflag = atoi(strtok(NULL,delim)); // 专业课有挂科 | |
int cflag = atoi(strtok(NULL,delim)); // CET有通过 | |
p[num].flags = (cflag & 1) * 2 + (pflag & 1); | |
// 个人觉得计算最后平均分放在这儿比较好. | |
// 所有内容额外遍历一遍计算需要花费更多的时间 | |
p[num].average = p[num].scores[0] * 0.6 + p[num].scores[1] * 0.3 + p[num].scores[2] * 0.1 ; | |
num ++; | |
} | |
// 空间申请了需要释放,文件打开了需要关闭 | |
fclose(fp); | |
return num; // 返回 读取过的行数 | |
} | |
void fun_sort(p_student p,int len) // qsort排序,把总成绩进行排名 | |
{ | |
qsort(p,len,sizeof(student),comp); | |
} | |
void fun_print_all(p_student p,int len) | |
{ | |
int i; | |
// 打表我们还是输出表头吧 | |
printf("%-10s %-10s %-5s %-8s %-10s %-8s %-8s %-8s %-8s %-10s\n", | |
"学号","姓名","班级","专业", | |
"专业均分","科技加分","社会加分", | |
"专业挂科","CET4通过", | |
"综合"); | |
for(i=0;i<len;i++) | |
{ | |
// 其实可以调节下让输出平整的,不过就这样吧 | |
printf("%-10d %-10s %-5d %-8s %-10d %-8d %-8d %-8s %-8s %.2f\n", | |
p[i].stu_id,p[i].name,p[i].class_id,p[i].profession, | |
p[i].scores[0],p[i].scores[1],p[i].scores[2], | |
(p[i].flags%1?"是":"否"), | |
((p[i].flags/2)%2?"是":"否"), | |
p[i].average); | |
} | |
printf("共%d条信息\n",len); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment