前言:
我们承接上文,再看此篇博客之前,我建议大家可以温习一下文件操作1哦,这样更方便我们理解新的内容
1.文本文件和二进制文件
文件的分类我们当作了解即可
根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文
本文件。
一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而
二进制形式输出,则在磁盘上只占4个字节(VS2013测试)。
#include <stdio.h>
int main()
{
int a = 10000;
FILE* pf = fopen("test.txt", "wb");
fwrite(&a, 4, 1, pf);//二进制的形式写到文件中
fclose(pf);
pf = NULL;
return 0; }
我们进入重点
2.sscanf和sprintf
struct S
{
int n;
float score;
char arr[10];
};
int main()
{
struct S s = { 100,3.14f,"bit" };
struct S tmp = { 0 };
char buf[1024] = { 0 };
//把格式化的数据转换成字符串存储输出到buf
sprintf(buf,"%d %f %s",s.n,s.score,s.arr);
//printf("%s\n", buf);
//从buf中读取格式化的数据输入到tmp中
sscanf(buf,"%d %f %s",&(tmp.n),&(tmp.score),tmp.arr);
printf("%d %f %s",tmp.n,tmp.score,tmp.arr);
return 0;
}
3.对比一组函数
scanf/fscanf/sscanf
printf/fprintf/sprintf
4.二进制形式的输入输出(超级重点!!!)
4.1 二进制写文件fwrite
即将信息以二进制的形式写入test.txt文件
其中的四个参数重点说明一下
struct S
{
char name[20];
int age;
double score;
};
int main()
{
struct S s[2] = { {"张三",20,55.6},{"李四",18,99.9}};
FILE* pf = fopen("test.txt","wb");
if (pf == NULL)
{
return 0;
}
//二进制的形式写文件
fwrite(&s,sizeof(struct S),2,pf);
fclose(pf);
pf = NULL;
return 0;
}
4.2 二进制读文件fread
即将信息从test.txt文件中读出,保存在tmp中
struct S
{
char name[20];
int age;
double score;
};
int main()
{
//struct S s = { "张三",20,55.6 };
struct S tmp[2] = { 0 };
FILE* pf = fopen("test.txt","rb");
if (pf == NULL)
{
return 0;
}
//二进制的形式读文件
fread(&tmp,sizeof(struct S),2,pf);
printf("%s %d %lf\n",tmp[0].name,tmp[0].age,tmp[0].score);
printf("%s %d %lf\n", tmp[1].name, tmp[1].age, tmp[1].score);
fclose(pf);
pf = NULL;
return 0;
}
看到这里通讯录文件升级版就可以看懂啦
5.文件的随机读取
注:
SEEK_CUR 文件指针的当前位置
SEEK_END 文件的末尾位置
SEEK_SET 文件的起始位置
我们读取字符是读指针右边哦(举例2读c,5读5,-3读d)
5.1 fseek(随机读取)
三个参数:1.目标文件指针 2.偏移量 3.文件指针的当前位置
根据文件指针的位置和偏移量来定位文件指针
我们在test.txt文件中写abcdef,以读文件形式打开,
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
return 0;
}
//定位文件指针
fseek(pf,2,SEEK_CUR);//c
//fseek(pf,-2,SEEK_END);//e
//fseek(pf,2,SEEK_SET);//c
//读取文件
int ch = fgetc(pf);
printf("%c\n",ch);//c
fclose(pf);
pf = NULL;
}
5.2 ftell(返回相对偏移量)
返回文件指针相对于起始位置的偏移量
int main()
{
FILE* pf = fopen("test.txt","r");
if (pf == NULL)
{
return 0;
}
//定位文件指针
//fseek(pf,-2,SEEK_END);//printf输出4
//fgetc(pf);//printf输出1
int pos = ftell(pf);
printf("%d\n",pos);
fclose(pf);
pf = NULL;
return 0;
}
5.3 rewind(文件指针回到起始位置)
我们先读一个a,此时文件指针偏移量为1,然后rewind是文件指针回到起始位置,再次读取,结果还是a
int main()
{
FILE* pf = fopen("test.txt","r");
if (pf == NULL)
{
return 0;
}
int ch=fgetc(pf);
printf("%c\n",ch);//a
int pos1=ftell(pf);
printf("%d\n", pos1);//1
rewind(pf);//文件指针回到起始位置了
int pos2 = ftell(pf);
printf("%d\n", pos2);//0
ch = fgetc(pf);
printf("%c\n",ch);//a
fclose(pf);
pf = NULL;
return 0;
}
6. 文件读取结束的判定
6.1 被错误使用的feof(EOF-文件结束的标志,返回值-1)
牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。
而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。
1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:
fgetc 判断是否为 EOF .
fgets 判断返回值是否为 NULL .
2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如:
fread判断返回值是否小于实际要读的个数
例 EOF
我们将文件中的信息删除,留下一个空文件
EOF-文件结束的标志,返回值-1
//feof文件结束的标志,在文件读取的过程中,不能用feof判断文件是否结束,feof应当用于文件结束时判断是读取失败而结束
int main() //还是遇到文件尾而结束
{
//feof //EOF-end of file-文件结束标志
FILE* pf = fopen("test.txt","r");
if (pf==NULL)
{
return 0;
}
int ch = fgetc(pf);
printf("%d\n",ch);//-1,feof(返回值-1)
fclose(pf);
pf = NULL;
return 0;
}
6.2 判断文件结束的原因
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("open file test.txt");
return 0;
}
//读文件
int ch = 0;
while ((ch = fgetc(pf)) != EOF)
{
putchar(ch);
}//文件结束
if (ferror(pf))//ferror返回值为真进入
{
printf("error\n");//读取失败结束
}
else if(feof(pf))//feof返回非0进入
{
printf("\n end of file\n");//遇见文件尾结束
}
fclose(pf);
pf = NULL;
return 0;
}
7.perror报错函数
strerror-把错误码对应的错误信息的字符串地址返回
perror:会先把你写的提示信息打印,然后再返回错误码对应的信息
int main()
{
//strerror-把错误码对应的错误信息的字符串地址返回
//printf("%s\n",strerror(errno));
FILE* pf = fopen("test2.txt", "r");
if (pf == NULL)
{
//perror的输出是open file test2.txt :错误信息
perror("open file test2.txt");//这一长串(open file test2.txt)写啥都行,就是一个提示
return 0;
}
//读文件
fclose(pf);
pf = NULL;
return 0;
}
留言:
到这里关于文件操作的知识就讲解完成了,希望小伙伴们多多思考练习,欢迎评论区留言讨论,收藏点赞支持一下吧!