文件读写的函数
字符读写 fgetc()/fputc()
字符串读写 fputs()/fgets()
格式化读写 fscanf()/fprintf()
二进制读写:fread()/fwrite()
其他相关函数:
检测文件结束的函数:feof()
检测文件读写时出错函数:ferror()
清楚末尾文件标志和出错标志函数:clearerr()
文件定位函数:fseek(),rewind(),ftell();
fseek函数:
用法:int fseek( FILE *stream, long offset, int origin );
函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
第一个参数stream为文件指针
第二个参数offset为偏移量,正数表示正向偏移,负数表示负向偏移
第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END依次为0,1和2.
#include<stdio.h>
#define N 5
typedef struct student{
long sno;
char name[10];
float score[3];
}STU;
void fun(char*filename,STU n)
{
FILE*fp;
fp=fopen(filename,"rb+");
fseek(fp,-1L*sizeof(STU),SEEK_END);
fwrite(&n,sizeof(STU),1,fp);
fclose(fp);
}
int main()/*修改覆盖最后一个学生数据*/
{
STU t[N]={
{10001,"MaChao",91,92,77},
{10002,"CaoKai",75,60,88},
{10003,"LiSi",85,70,78},
{10004,"FangFang",90,82,87},
{10005,"ZhangSan",95,80,88}
};
STU n={10006,"ZhaoSi",55,70,68},ss[N];
int i,j;FILE*fp;
fp=fopen("student.dat","wb");
fwrite(t,sizeof(STU),N,fp);
fclose(fp);
fp=fopen("student.dat","rb");
fread(ss,sizeof(STU),N,fp);
fclose(fp);
printf("
The original data:
");
for(j=0;j<N;j++)
{
printf("
No:%ldName:%-8sScores:",ss[j].sno,ss[j].name);
for(i=0;i<3;i++)
printf("%6.2f",ss[j].score[i]);
printf("
");
}
fun("student.dat",n);
printf("
The data after modifing:
");
fp=fopen("student.dat","rb");
fread(ss,sizeof(STU),N,fp);
fclose(fp);
for(j=0;j<N;j++)
{
printf("
No:%ldName:%-8sScores:",ss[j].sno,ss[j].name);
for(i=0;i<3;i++)
printf("%6.2f",ss[j].score[i]);
printf("
");
}
return 0;
}
rewind()函数
将文件内部的指针重新指向一个流的开头
函数作用等同于 (void)fseek(stream, 0L, SEEK_SET);
用 法: void rewind(FILE *stream);
EOF:
通常在文本的最后存在此字符表示资料结束;
和feof的返回值不是一个概念
ftell()函数
用于得到文件位置(文件的第一个字节所在位置是零)指针当前位置相对于文件首的偏移字节数
用法:long ftell(FILE *stream);
结构体的输入和输出:
结构体的定义:
结构体的初始化:
结构体内容的修改:
/*输入n(3<n<=10)个职工的编号、姓名、基本工资、职务工资,输出其中“基本工资+职务工资”最少和最多的职工姓名。
输入输出示例:
n=5
1,林宏,1800,600
2,李涛,1700,550
3,王钢,2100,750
4,周航,1500,450
5,金明,2300,850
基本工资+职务工资最少的是:周航
基本工资+职务工资最多的是:金明
*/
#include<stdio.h>
struct Worker//变量类型的定义,即定义一个结构体类型,结构体本质就是一个新的变量类型,可以用于存放多组不同变量类型的数据
{ int num;//可以包含整型
char name[20];//字符型(一维二维均可以表示)
float jbpay;//浮点型
float zwpay;
};
int main()
{
______1_______;//定义一个结构体变量,用构造的结构体类型来定义一个变量,类似于int/float/char..., int x;
//答案为 :struct Worker s[10] 这边有个困惑是,为什么要加[10],其实是定义一个结构体数组,当有多组数据需要存储时,使用结构体数组来存储每一条变量数据。
int max=0,min=0,i,n;
printf("n=");
scanf("%d",&n);
getchar();
for (i=0;i<n;i++)
{
scanf("%d%s%f%f",______2______);//结构体变量的输入,需要对每一项结构体成员分别输入,不同类型的成员用不同类型的格式符输入;
if(s[max].jbpay+s[max].zwpay <s[i].jbpay+s[i].zwpay ) ______3_______;
if(s[min].jbpay+s[min].zwpay >s[i].jbpay+s[i].zwpay )______4_______;
getchar();
}
printf("基本工资+职务工资最少的是%s
",s[min].name);//结构体成员的引用使用 结构体变量名.结构体成员,"."号表示引用,
printf("基本工资+职务工资最多的是%s
",s[max].name);
return 0;
}
结构体成员运算符:
->指针运算符。
1、如果结构体中的成员均为一般变量(包括结构体变量),则使用容“.”,如果成员变量为指针(不管指向什么,包括结构体),则使用“->”。
2、如果定义了结构体数组指针,则可分别使用“.”和“->”,区别在于指针带下标时,以是数组形式访问,此时用“.”,如果不带下标(或使用偏移),此时用“->”。
(->)是一个表示成员的运算符,它与前面讲过的·运算符的区别是:
(->)用来表示指向对象的指针的成员,表示数据成员。
(·)用来表示一般对象的成员,表示成员函数。
下面的两种表示是等价的:
<对象指针名>-><成员名>
与
(*<对象指针名>).<成员名>
这对于成员函数也适用。
另一说:
成员运算符(·)和指向结构体成员运算符(->)的区别
两者都是用来引用结构体变量的成员,但它们的应用环境是完全不一样,前者是用在一般结构体变量中,而后者是与指向结构体变量的指针连用,例如:有定义
struct student
{
long num;
float score;
};
struct student stud, *ptr=&stud;
则stud.num、stud.score、ptr->num等都是正确的引用方式,但ptr.num、stud->num就是不允许的,其实ptr->num相当于(*ptr).num,只是为了更为直观而专门提供了这->运算符。
最后指出,这两者都具有最高优先级,按自左向右的方向结合
/*
修改结构体中的数据
程序通过定义学生结构体变量,存储了学生的学号、姓名和3门课的成绩。
函数fun的功能是将形参a所指结构体变量s中的数据进行修改,并把a中地址作为函数值返回主函数,在主函数中输出修改后的数据。
例如:a所指变量s中的学号、姓名、和三门课的成绩依次是:
10001、" ZhangSan "、95、80、88,
修改后输出t中的数据应为:10002、"LiSi "、96、81、89。
注意:按照顺序填代码,不要带编号1,2,3,4。空格或回车隔开。*/
#include <stdio.h>
#include <string.h>
struct student {
long sno;
char name[10];
float score[3];
};
______2__________ Modif(struct student *p)//定义一个结构体指针,返回类型为结构体指针类型,故答案为struct student *
{
int i;
p->sno = 10002;//若成员为整型数据,则可以使用直接赋值的方法,指针指向结构体成员然后赋值,使用箭头运算符
strcpy(p->name, "LiSi");//若成员为字符串型数据,则必须使用相关函数(strcpy()),不能够直接赋值!!!
for (i=0; i<3; i++)//对于成员为数组的变量,则修改时必须使用循环,每一条数据修改方式同上两条
______3_______++;//p->score[i]
return _____4________;//返回值为p指针,用于使用箭头指针运算符,修改的只有成员的数据,并未修改指针p的位置,所以返回时无需返回第一个成员变量的地址。
}
void main()
{
struct student s={10001,"ZhangSan", 95, 80, 88}, *t;//主函数中,结构体变量的初始化必须紧跟在结构体变量的定义之后,否则视为违法操作
int i;
printf("
The original data :
");
printf("
No: %ld Name: %s
Scores: ",s.sno, s.name);
for (i=0; i<3; i++)
printf("%6.2f ", ___1____);//输出修改前的数据
printf("
");
t = Modif(&s);//将函数的返回值赋给一个结构体指针
printf("
The data after modified :
");
printf("
No: %ld Name: %s
Scores: ",t->sno, t->name);
for (i=0; i<3; i++)//对于数据,使用循环输出
printf("%6.2f ", t->score[i]);//输出修改后的数据
return 0;
}
/*
1.下述数据,结构体如何定义?
2.现有100部电影数据,如何存储。
3.定义结构体指针怎么定义?
4.修改第三条数据为 {F001,前任4,60,10:30},怎么改?
5de3e2937fa3d.png?OSSAccessKeyId=LTAItfPkNIKJFibY&Expires=4728815763&Signature=Xr2bX%2F1MQ%2FiSKjefgQCdNcxcIj8%3D
*/
/*正确答案:
第一空:*/
typedef struct {//使用typedef 来给定义的结构体类型起一个名字,以便于接下来对于结构体变量的定义,倘若不使用typedef,定义结构体变量就得使用
// struct MyStruct+变量名
char filmNum[10];//定义电影编号,包含英文字母,故使用字符数组
char filmName[100];//名字类使用字符数组
int filePrice;//电影价
char fileTime[20];//对于时间的存储????
}FILM;
FILM films[100];
FILM *p = films;//定义结构体指针来移动到需要修改的位置
p=p+2;
strcpy(p->filmNum,"F001");//注意字符的修改需要使用字符的相关函数(strcpy)
strcpy(p->filmName,"前任4");
p->filmPrice=60;
strcpy(p->filmTime,"10:30")
/*我的答案:
第一空:
1.*/
typedef struct
{
char num[50];
char name[30];
double price;
char datetime[70][70];
}MOVIEDATA;
MOVIEDATA data;
data = (MOVIEDATA)malloc(sizeof(MOVIEDATA)10000);
strcpy=(data[3].num,"F001");
strcpy=(data[3].name,"前任4");
data[3].price=60;
int i=0;
strcpy=(data[3].datetime[i],'10');
i++;
strcpy=(data[3].datetime[i],'30');
/*
以下程序中用户由键盘输入一个文件名,然后输入一串字符(用#结束输入)存放到此文件文件中形成文本文件,并将字符的个数写到文件尾部。文件名要加上后缀txt,如“hello.txt”
思路是,先将输入的文件名写入文件中(救赎创建一个文件),再写入文本到这个文件
*/
include <stdio.h>
include <stdlib.h>
int main(void){
FILE *fp;
char ch,fname[32];
int count=0;
printf("Input the filename :");
scanf("%s",fname);//文件可以来自键盘输入的字符串??打开的文件可以来自于键盘输入的字符串???
if (1_==NULL) {//(fp=fopen(fname,"w+"))使用写入文件的写法 将文件指针指向打开后的文件,文件使用文件打开函数打开,
printf("Can't open file:%s
",fname);
exit(0);
}
printf("Enter data: ");
while ((ch=getchar())!='#') {//循环条件是没有到结束标志
_________2______________;//将字符写入到文件当中去,fputc(ch,fp)
count++;//计算文件的长度
}
fprintf(3_________);// fp," %d ",count,将字符的个数写到文件尾部,注意,在文件中的输出和写入,使用的函数和在屏幕上的不同。
fclose(fp);
}
正确答案:
第一空:
(fp=fopen(fname,"w+"))
第二空:
fputc(ch,fp)
第三空:
fp,"
%d
",count
我的答案:
第一空:
fp=fopen("fname.txt","w")
第二空:
fputs(ch,fp)
第三空:
("%d",count)