练习:针对fscanf和fprintf练习
有如下结构体:
typedef struct Student
{
char name[20];
int id;
float chinese;//语文成绩
float math;
float english;
float physical;
float chemical;
float biological; }stu_t; *Pstu_t//声明学生结构体类型
在栈区静态开辟空间或堆区动态开辟空间,用于接收学生信息
编写2个.c文件,save.c 和 load.c save.c负责: 使用fprintf将3个学生的所有信息保存到文件中去 load.c负责: 使用fscanf读取文件中的3个学生的信息,将读取到的数据,保存到另一个开辟的空间中去,并输出空间中的内容 最终实现效果: 运行save.c,会将准备的学生信息写入文件中 运行load.c,会将文件中的所有学生信息输出到终端上
代码实现:
#include <myhead.h>
#define MAX 3
typedef struct Student{//定义一个学生信息的结构体
char name[20];
int id;
double chinese;
double math;
double english;
double physical;
double chemical;
double biological;
}stu_t,*Pstu_t;
void input_stu(Pstu_t p){//在终端向p指向的空间输入学生信息
int i;
for(i=0;i<MAX;i++){//终端输入学生信息
printf("请输入第%d个学生信息:",i+1);
scanf("%s%d%lf%lf%lf%lf%lf%lf",(p+i)->name,&(p+i)->id,&(p+i)->chinese,
&(p+i)->math,&(p+i)->english,&(p+i)->physical,&(p+i)->chemical,&(p+i)->biological);
}
}
void save_stu(const char *file,Pstu_t p){//将p指向的学生信息内容保存到文件中
FILE *fp=fopen(file,"w");
if(NULL==fp){
perror("文件打开失败");
return;
}
int i;
for(i=0;i<MAX;i++){
fprintf(fp,"%s %d %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf\n",(p+i)->name,(p+i)->id,(p+i)->chinese,
(p+i)->math,(p+i)->english,(p+i)->physical,(p+i)->chemical,(p+i)->biological);
}
fclose(fp);
}
void load_stu(const char *file,Pstu_t p){//将文件中学生信息读取到p指向的空间中,并终端打印学生信息
FILE *fp=fopen(file,"r");
if(NULL==fp){
perror("文件打开失败");
return;
}
int i=0;
while(1){//将文件中学生信息读取到p指向的空间中
int res=fscanf(fp,"%s%d%lf%lf%lf%lf%lf%lf",(p+i)->name,&(p+i)->id,&(p+i)->chinese,
&(p+i)->math,&(p+i)->english,&(p+i)->physical,&(p+i)->chemical,&(p+i)->biological);
//对于%s%d%lf遇到与自己类型不匹配的情况时,读取结束,并且光标保持在下一个位置,对于空格和换行是结束,同时,光标位于空格或换行后一个字符
//%c是所有字符都吸收,包括空格和换行
if(EOF==res){
break;
}
i++;
}
fclose(fp);
for(i=0;i<MAX;i++){//终端打印学生信息
printf("第%d个学生信息:\n姓名:%s\n学号:%d\n语文:%.2lf\n数学:%.2lf\n英语:%.2lf\n物理:%.2lf\n化学:%.2lf\n生物:%.2lf\n",i+1,
(p+i)->name,(p+i)->id,(p+i)->chinese,(p+i)->math,(p+i)->english,(p+i)->physical,
(p+i)->chemical,(p+i)->biological);
}
}
int main(int argc, const char *argv[])
{
//使用动态内存开辟空间实现
Pstu_t p=(Pstu_t)malloc(sizeof(stu_t)*MAX);
if(NULL==p){
perror("空间开辟失败");
return 1;
}
input_stu(p);
save_stu(argv[1],p);
Pstu_t ps=(Pstu_t)malloc(sizeof(stu_t)*MAX);
if(NULL==ps){
perror("空间开辟失败");
return 1;
}
load_stu(argv[1],ps);
free(p);
p=NULL;
free(ps);
ps=NULL;
return 0;
}
有如下结构体:
typedef struct Student
{
char name[20];
int id;
float chinese;//语文成绩
float math;
float english;
float physical;
float chemical;
float biological; }stu_t; *Pstu_t//声明学生结构体类型
创建链表,用于接收学生信息和传递学生信息
编写2个.c文件,save.c 和 load.c save.c负责: 使用fprintf将3个学生的所有信息保存到文件中去 load.c负责: 使用fscanf读取文件中的3个学生的信息,将读取到的数据,保存到另一个开辟的空间中去,并输出空间中的内容 最终实现效果: 运行save.c,会将准备的学生信息写入文件中 运行load.c,会将文件中的所有学生信息输出到终端上
代码实现 :
#include <myhead.h>
#define MAX 3
typedef struct Student{//定义一个学生信息的结构体
char name[20];
int id;
double chinese;
double math;
double english;
double physical;
double chemical;
double biological;
}stu_t,*Pstu_t;
typedef struct stu{//定义单链表结构体
union{
int len;
stu_t data;
};
struct stu *next;
}Link,*Plink;
Plink create(){//开辟头节点
Plink p=(Plink)malloc(sizeof(Link));
if(NULL==p){
perror("空间开辟失败");
return NULL;
}
p->len=0;
p->next=NULL;
return p;
}
void input_stu(Pstu_t p){//在终端向p指向的学生结构体空间输入学生信息
printf("请输入学生信息:");
scanf("%s%d%lf%lf%lf%lf%lf%lf",p->name,&p->id,&p->chinese,
&p->math,&p->english,&p->physical,&p->chemical,&p->biological);
}
int insert_tail(Plink L,stu_t data){//采用尾插法插入学生信息
Plink p=(Plink)malloc(sizeof(Link));
if(NULL==p){
perror("空间开辟失败");
return 1;
}
p->data=data;
Plink t=L;
while(t->next!=NULL){
t=t->next;
}
p->next=t->next;
t->next=p;
L->len++;
return 0;
}
void save_stu(const char *file,Plink p){//将p指向的学生信息内容保存到文件中
FILE *fp=fopen(file,"w");
if(NULL==fp){
perror("文件打开失败");
return;
}
Plink t=p->next;
while(t!=NULL){
fprintf(fp,"%s %d %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf\n",t->data.name,t->data.id,t->data.chinese,
t->data.math,t->data.english,t->data.physical,t->data.chemical,t->data.biological);
t=t->next;
}
fclose(fp);
}
void load_stu(const char *file,Plink p){//将文件中学生信息读取到p指向的空间中,并终端打印学生信息
FILE *fp=fopen(file,"r");
if(NULL==fp){
perror("文件打开失败");
}
while(1){//将文件中学生信息读取到p指向的空间中
stu_t data;
int res=fscanf(fp,"%s%d%lf%lf%lf%lf%lf%lf",data.name,&data.id,&data.chinese,
&data.math,&data.english,&data.physical,&data.chemical,&data.biological);
//对于%s%d%lf遇到与自己类型不匹配的情况时,读取结束,并且光标保持在下一个位置,对于空格和换行是结束,同时,光标位于空格或换行后一个字符
//%c是所有字符都吸收,包括空格和换行
if(EOF==res){
break;
}
insert_tail(p,data);//插入新节点,存储数据
}
fclose(fp);
Plink t=p->next;
while(t!=NULL){//终端打印学生信息
printf("学生信息:\n姓名:%s\n学号:%d\n语文:%.2lf\n数学:%.2lf\n英语:%.2lf\n物理:%.2lf\n化学:%.2lf\n生物:%.2lf\n",
t->data.name,t->data.id,t->data.chinese,t->data.math,t->data.english,t->data.physical,
t->data.chemical,t->data.biological);
t=t->next;
}
}
//空间释放
void free(Plink p){
Plink t=p;
while(t!=NULL){
t=t->next;
free(p);
p=t;
}
}
int main(int argc, const char *argv[])
{
//创建单链表实现
Plink L=create();
int i;
for(i=0;i<MAX;i++){
stu_t data;
input_stu(&data);
insert_tail(L,data);
}
save_stu(argv[1],L);
//创建新表头
Plink K=create();
load_stu(argv[1],K);
free(L);
free(K);
return 0;
}
结果: