#include <stdioh>
#define SCORERADIX 07
typedef struct tagScore
{
double m_nSumScore;
long m_lACM;
int m_nClass;
int m_nDone;
int m_nScore;
char m_strName[15];
}SCORE,PSCORE;
int main()
{
FILE fpSrc = NULL,fpDst = NULL;
PSCORE pScore = NULL;
long lCnt = 0l,i = 0l;
int nIncr = 0;
fpSrc = fopen("scoretxt","r");
if (NULL == fpSrc)
{
/提示信息/
goto CLEARNNONE;
}
fpDst = fopen("ranktxt","w");
if (NULL == fpDst)
{
/提示信息/
goto CLEARNSRC;
}
if (EOF == fscanf(fpSrc,"%ld",&lCnt) || lCnt < 0l)
{
/提示信息/
goto CLEARNALL;
}
pScore = (PSCORE)calloc(lCnt,sizeof(SCORE));
if (NULL == pScore)
{
/提示信息/
goto CLEARNALL;
}
for(i = 0l;i < lCnt;++i)
{
if (EOF == fscanf(fpSrc,"%s%ld%d%d%d",pScore[i]m_strName,&pScore[i]m_lACM,&pScore[i]m_nClass,&pScore[i]m_nDone,&pScore[i]m_nScore))
{
/提示信息/
break;
}
pScore[i]m_nSumScore = (double)pScore[i]m_nScore SCORERADIX;
nIncr = pScore[i]m_nClass + pScore[i]m_nDone;
if (pScore[i]m_lACM >= 80)
{
nIncr = 30;
}
else if (pScore[i]m_lACM > 30)
{
nIncr += ((pScore[i]m_lACM - 30) / 10) 2;
if (nIncr > 30)
{
nIncr = 30;
}
}
else
{
/do nothing/
}
pScore[i]m_nSumScore += nIncr;
}
/排序/
for(i = 0l;i < lCnt;++i)
{
//
}
/输出/
for(i = 0l;i < lCnt;++i)
{
fprintf(fpDst,"%s %f\n",pScore[i]m_strName,pScore[i]m_nSumScore);
}
CLEARNALL:
free(pScore);
fclose(fpDst);
CLEARNSRC:
fclose(fpSrc);
CLEARNNONE:
return 0;
}
void
writefile(tree
t)
{
FILE
fp;
if
(t
==
NULL)
{
return;
}
if
((fp
=
fopen(FILENAME,
"wb"))
==
NULL)
{
printf("can't
open
file
%s\n",
FILENAME);
return;
}
preorder(t,
fp);
fclose(fp);
}
tree
readfile(tree
t)
{
TSTUDENT
r_new;
FILE
fp;
if
((fp
=
fopen(FILENAME,
"rb"))
!=
NULL)
{
printf("
======Read
from
this
file,
Please
wait=====\n");
while(fread(&r_new,
sizeof(TSTUDENT),
1,
fp)
==
1)
{
inn
=
(PSTUDENT)malloc(sizeof(TSTUDENT));
inn
=
r_new;
t
=
insert(defaultIndex,
t);
}
fclose(fp);
}
return
t;
}
/
关键之处是要注意使用二进制文件,文本文件可能会忽略掉某些字符,导致读取失败,或读到的全是乱码/
1、对齐方式。
程序编译时,可以选择对齐方式,如4字节对齐,8字节对齐。如果两个程序对齐方式不一致,可能导致结构体的大小在两个程序中不一样。可以用pragma
pack包围定义的结构体,设置对齐。
#pragma
pack(1)
struct
#pragma
pack()
2、Big-Endian与Little-Endian。
如果文件是在一台机器上写,另一台机器上读,可能因为CPU的大小头不一致,导致读出的数字不正确。需要进行大小头转换。(如X86的是小头,Power的是大头)
看程序就是把内存直接写到文件里了。虽然可以,但一般不这样做。因为随着程序的扩展,结构体可能要增改变量。推荐用 protobuf 或 thrift 或 json 等等的序列化协议,把内存中的内容序列化成字符串,写入文件。读取的时候再反序列化回内存对象。
512行的
#include<stdioh>
#include<stdlibh>
#include<stringh>
#include<malloch>
//函数声明
int menu(); //菜单
struct scorenode create(void); //创建链表,并返回链表的头指针
struct scorenode load(); //调用导入学生记录函数
struct scorenode search(struct scorenode ); //成绩查询函数
struct scorenode del(struct scorenode ); //删除学生资料
struct scorenode add(struct scorenode ); //追加学生资料
void print_s(struct scorenode ); //显示学生资料
void statistics(struct scorenode ); //统计学生成绩函数
void save(struct scorenode ); //保存学生资料
void sort(struct scorenode ); //排序函数
//数据定义
struct scorenode
{
int number; //学号
char name[10]; //姓名
float physics; //物理成绩
float english; //英语成绩
float maths; //数学成绩
struct scorenode next; //存储下一个结点的地址
};
int n; //n为全局变量,存储录入的人数
//主程序
void main()
{
struct scorenode head=NULL,stu=NULL; //定义链表头指针为空
int k;
while(1)
{
k=menu();
switch(k)
{
case 1:head=create();break; //创建链表,录入数据
case 2:head=load();break; //调用导入学生函数
case 3:head=search(head);break; //成绩查询函数函数
case 4:head=del(head);break; //删除学生资料函数
case 5:head=add(head);break; //追加学生资料函数
case 6:print_s(head);break; //显示学生资料函数
case 7:statistics(head);break; //统计学生成绩函数
case 8:save(head);break; //保存学生的资料
case 9:sort(head);break; //排序函数
case 0:exit(0);
default:printf("输入错误,请重试!\n");
}
}
}
//菜单选择界面
int menu()
{
int i,k;
printf("\n\t\t\t欢迎进入成绩管理系统\n\n");
printf("\t\t\t 04电子应用\n");
for(i=0;i<80;i++)
printf("");
printf("1输入学生的资料\t 2从文件调入资料\t 3查询学生的成绩\n");
printf("4删除学生的资料\t 5追加学生的资料\t 6显示学生的成绩\n");
printf("7统计学生的成绩\t 8保存输入的资料\t 9对成绩进行排序\n");
printf("0退出\n");
for(i=0;i<80;i++)
printf("");
printf("请选择您的 *** 作:");
scanf("%d",&k); //读取输入的选择
getchar(); //吸收回车符
return(k);
}
//创建链表,并返回链表的头指针
struct scorenode create(void)
{
struct scorenode head=NULL; //定义链表头指针为空
struct scorenode p1,p2,p3;
int i;
n=0;
p1=p2=p3=(struct scorenode)malloc(sizeof(struct scorenode)); //开辟一个新的存储单元
while(1)
{
printf("请输入学生资料,输(0)退出!\n");
repeat:
printf("请输入学号(学号应大于0):");
scanf("%d",&p1->number);
while(p1->number<0) //判断输入学号是否正确
{
printf("输入错误,请重新输入学号:");
scanf("%d",&p1->number);
}
getchar(); //吸收回车符
if(p1->number==0) //输入为0,退出
goto endd;
else
{
p3=head;
if(n>0)
{
for(i=0;i<n;i++)
{
if(p1->number!=p3->number) //判断输入的学号是否重复
p3=p3->next;
else
{
printf("学号重复,请重输!\n");
goto repeat;
}
}
}
}
printf("请输入姓名:");
scanf("%s",&p1->name);
printf("请输入物理,英语,数学成绩(0-100):");
scanf("%f,%f,%f",&p1->physics,&p1->english,&p1->maths);
while(p1->physics<0||p1->physics>100||p1->english<0||p1->english>100
||p1->maths<0||p1->maths>100) //判断输入的成绩数据是否正确
{
printf("输入错误,请重新输入成绩:");
scanf("%f,%f,%f",&p1->physics,&p1->english,&p1->maths);
}
getchar(); //吸收回车符
n=n+1; //录入的人数加1
if(n==1)
head=p1;
else
{
p2->next=p1;
p2=p1; //存储此次录入的数据
}
p1=(struct scorenode)malloc(sizeof(struct scorenode)); //开辟一个新的存储单元
}
endd:
p2->next=NULL;
save(head);
return(head); //返回此次录入的链表值
}
//保存学生资料
void save(struct scorenode p1)
{
FILE fp;
if((fp=fopen("scrocetxt","w"))==NULL)
{
printf("不能打开文件!\n");
}
while(p1!=NULL)
{
fprintf(fp,"%d\t%s\t%1f\t%1f\t%1f\n",p1->number,p1->name,p1->physics,
p1->english,p1->maths);
p1=p1->next; //下移一个结点
}
fclose(fp);
printf("文件已保存!\n");
}
//调用导入学生记录函数
struct scorenode load()
{
FILE fp;
struct scorenode p1,p2,head;
int m=0;
if((fp=fopen("scrocetxt","r"))==NULL) //打开文件
{
printf("不能打开文件!\n");
return 0;
}
printf("\n\t\t成绩管理系统\n\n");
printf("\t\t 04电子应用\n");
printf("---------------------------------------------------------\n");
printf("学号\t姓名\t物理\t英语\t数学\t\n");
printf("---------------------------------------------------------\n");
head=NULL;
p1=p2=(struct scorenode)malloc(sizeof(struct scorenode)); //开辟一个新的存储单元
while(!feof(fp)) //文件是否结束
{
fscanf(fp,"%d%s%f%f%f",&p1->number,&p1->name,&p1->physics,
&p1->english,&p1->maths); //从文件中读入数据
printf("%d\t%s\t%1f\t%1f\t%1f\n",p1->number,p1->name,p1->physics,
p1->english,p1->maths); //打印数据
m=m+1;
if(m==1)
head=p1;
else
{
p2->next=p1; //指向下一个节点
p2=p1;
}
p1=(struct scorenode)malloc(sizeof(struct scorenode)); //开辟一个新的存储单元
}
p2->next=NULL;
printf("---------------------------------------------------------\n");
fclose(fp);
return head;
}
//成绩查询函数
struct scorenode search(struct scorenode head)
{
int number;
struct scorenode p1,p2;
printf("\n请输入要查询的学生的学号(0)退出:");
scanf("%d",&number); //读取输入的学号
printf("---------------------------------------------------------\n");
printf("学号\t姓名\t物理\t英语\t数学\t\n");
printf("---------------------------------------------------------\n");
while(number!=0) //输入是0,退出
{
getchar(); //吸收回车符
if(head==NULL) //判断链表中是否有数据
{
printf("\n没有任何学生资料!\n");
return(head);
}
p1=head;
while(number!=p1->number&&p1->next!=NULL) //判断链表中数据是否结束
{
p2=p1;
p1=p1->next; //指向链表下一个结点
}
if(number==p1->number)
{
printf("%d\t%s\t%1f\t%1f\t%1f\n",p1->number,p1->name,p1->physics,
p1->english,p1->maths); //打印数据
printf("---------------------------------------------------------\n");
}
else
printf("%d号学生不存在!\n",number);
printf("输入要查询的学生的学号(0)退出:");
scanf("%d",&number);
}
printf("退出查询!\n");
return(head);
}
//删除学生资料
struct scorenode del(struct scorenode head)
{
struct scorenode p1,p2;
int number;
printf("\n请输入要删除的学生的学号(0)退出:");
scanf("%d",&number); //读取输入的学号
while(number!=0) //输入是0,退出
{
if(head==NULL) //判断链表中是否有数据
{
printf("\n没有任何学生资料!\n");
return(head);
}
p1=head;
while(number!=p1->number&&p1->next!=NULL) //判断链表中数据是否结束
{
p2=p1;
p1=p1->next; //指向链表下一个结点
}
if(number==p1->number)
{
if(p1==head) //判断链表是否是头指针
head=p1->next;
else
p2->next=p1->next; //删除链表
n=n-1; //学生人数减一
}
printf("输入要删除的学生的学号(0)退出:");
scanf("%d",&number);
}
printf("现在的学生数为:%d个!\n",n);
save(head); //保存资料
return(head);
}
//追加学生资料
struct scorenode add(struct scorenode head)
{
struct scorenode p0,p3,stu;
int i;
while(1)
{
stu=(struct scorenode)malloc(sizeof(struct scorenode)); //开辟一个新的存储单元
printf("\n输入要增加的学生资料!\n");
repeat2:
printf("请输入学号(学号应大于0):");
scanf("%d",&stu->number);
while(stu->number<0) //判断输入学号是否正确
{
printf("输入错误,请重新输入学号:");
scanf("%d",&stu->number);
}
if(stu->number==0) //输入为0,退出
goto end2;
else
{
p3=head;
if(n>0)
{
for(i=0;i<n;i++)
{
if(stu->number!=p3->number) //判断输入的学号是否重复
p3=p3->next;
else
{
printf("学号重复,请重输!\n");
goto repeat2;
}
}
}
}
printf("请输入姓名:");
scanf("%s",&stu->name);
printf("请输入物理,英语,数学成绩(0-100):");
scanf("%f,%f,%f",&stu->physics,&stu->english,&stu->maths);
while(stu->physics<0||stu->physics>100||stu->english<0||stu->english>100
||stu->maths<0||stu->maths>100) //判断输入的成绩数据是否正确
{
printf("输入错误,请重新输入成绩:");
scanf("%f,%f,%f",&stu->physics,&stu->english,&stu->maths);
}
getchar(); //吸收回车符
stu->next=NULL;
p0=head;
if(p0==NULL) //都没数据
{
head=stu; //存储新追加的数据
head->next=NULL;
}
else
{
while(p0->next!=NULL)
p0=p0->next;
p0->next=stu; //存储新追加的数据
}
n=n+1; //学生个数加1
}
end2:
printf("现在的学生数为:%d个!\n",n);
//sort(head);
save(head); //保存资料
return(head); //返回此次录入的链表值
}
//显示学生资料
void print_s(struct scorenode head)
{
struct scorenode p;
if(head==NULL)
printf("\n没有任何学生资料!\n");
else
{
printf("总人数:%d\n",n); //显示总人数
printf("---------------------------------------------------------\n");
printf("学号\t姓名\t物理\t英语\t数学\t\n");
printf("---------------------------------------------------------\n");
p=head;
while(p!=NULL)
{
printf("%d\t%s\t%1f\t%1f\t%1f\n",p->number,p->name,p->physics,
p->english,p->maths); //打印数据
p=p->next; //指向下一结点
}
printf("---------------------------------------------------------\n");
}
}
//统计学生成绩函数
void statistics(struct scorenode head)
{
float sum,sum1=0,sum2=0,sum3=0,ave,ave1=0,ave2=0,ave3=0,max=0,min=0;
struct scorenode p;
int y=0,i=0;
p=head;
if(head==NULL)
printf("\n没有任何学生资料!\n");
else
{
printf("---------------------------------------------------------\n");
printf("学号\t姓名\t物理\t英语\t数学\t总分\t平均分\n");
printf("---------------------------------------------------------\n");
while(p!=NULL)
{
sum=p->physics+p->english+p->maths; //计算个人总分
ave=sum/3; //计算个人平均分
printf("%d\t%s\t%1f\t%1f\t%1f\t%1f\t%1f\n",p->number,p->name,p->physics,
p->english,p->maths,sum,ave); //打印数据
sum1=sum1+p->physics; //累加物理分数
sum2=sum2+p->english; //累加英语分数
sum3=sum2+p->maths; //累加数学分数
y=y+1; //计算人数
if(max<sum)
max=sum; //计算最高分
else if(min>sum)
min=sum; //计算最低分
p=p->next; //指向下一结点
}
ave1=sum1/y; //计算物理平均分
ave2=sum2/y; //计算英语平均分
ave3=sum3/y; //计算数学平均分
printf("物理平均分:%1f\n",ave1);
printf("英语平均分:%1f\n",ave2);
printf("数学平均分:%1f\n",ave3);
printf("总分最高分:%1f\n",max);
printf("总分最低分:%1f\n",min);
printf("\n");
}
}
//结点中数据交换
void swap(struct scorenode max,struct scorenode p)
{
int k;
char t[10];
float temp;
k=max->number;
max->number=p->number;
p->number=k;
strcpy(t,max->name);
strcpy(max->name,p->name);
strcpy(p->name,t);
temp=max->physics;
max->physics=p->physics;
p->physics=temp;
temp=max->english;
max->english=p->english;
p->english=temp;
temp=max->maths;
max->maths=p->maths;
p->maths=temp;
}
//排序函数
void sort(struct scorenode head)
{
struct scorenode p,max;
int i,j,x;
if(head==NULL)
{
printf("\n没有任何学生资料,请先建立链表!\n");
}
for(i=0;i<80;i++)
printf("");
printf("1按学生学号排序\t2按学生姓名排序\t3按物理成绩排序\n");
printf("4按英语成绩排序\t5按数学成绩排序\n");
printf("请选择 *** 作(0)退出:");
scanf("%d",&x); //读取输入的选择
getchar();
for(i=0;i<80;i++)
printf("");
switch(x)
{
case 1: //学号排序
for(i=1;i<n;i++)
{
max=p=head;
p=p->next;
for(j=0;j<n-i;j++)
{
if(max->number>p->number)
swap(max,p);
p=p->next;
max=max->next;
}
}
print_s(head);break; //打印数据
case 2:
for(i=1;i<n;i++) //姓名排序(冒泡方式)
{
max=p=head;
p=p->next;
for(j=0;j<n-i;j++)
{
if(strcmp(max->name,p->name)>0)
swap(max,p);
p=p->next;
max=max->next;
}
}
print_s(head);break;
case 3:
for(i=1;i<n;i++) //按物理成绩排序
{
max=p=head;
p=p->next;
for(j=0;j<n-i;j++)
{
if(max->physics>p->physics)
swap(max,p);
p=p->next;
max=max->next;
}
}
print_s(head);break;
case 4:
for(i=1;i<n;i++) //按英语成绩排序
{
max=p=head;
p=p->next;
for(j=0;j<n-i;j++)
{
if(max->english>p->english)
swap(max,p);
p=p->next;
max=max->next;
}
}
print_s(head);break;
case 5:
for(i=1;i<n;i++) //按数学成绩排序
{
max=p=head;
p=p->next;
for(j=0;j<n-i;j++)
{
if(max->maths>p->maths)
swap(max,p);
p=p->next;
max=max->next;
}
}
print_s(head);break;
case 0:
break;
}
save(head); //保存排序后的数据
}
以上就是关于c语言文件 *** 作,结构体全部的内容,包括:c语言文件 *** 作,结构体、C程序中如何从文本文件中读取数据到结构体中、C语言不同程序对同一个结构体的文件存储和读取等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)