文件操作2

前言:

我们承接上文,再看此篇博客之前,我建议大家可以温习一下文件操作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

文件操作2

文件操作2

我们进入重点

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("%sn", 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

文件操作2

4.二进制形式的输入输出(超级重点!!!)

4.1 二进制写文件fwrite

即将信息以二进制的形式写入test.txt文件

其中的四个参数重点说明一下

文件操作2

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;
}

文件操作2

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 %lfn",tmp[0].name,tmp[0].age,tmp[0].score);
printf("%s %d %lfn", tmp[1].name, tmp[1].age, tmp[1].score);
fclose(pf);
pf = NULL;
return 0;
}

文件操作2

看到这里通讯录文件升级版就可以看懂啦

5.文件的随机读取

注:

SEEK_CUR  文件指针的当前位置

SEEK_END 文件的末尾位置

SEEK_SET  文件的起始位置

文件操作2

我们读取字符是读指针右边哦(举例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("%cn",ch);//c
fclose(pf);
pf = NULL;
}

文件操作2

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("%dn",pos);
fclose(pf);
pf = NULL;
return 0;
}

文件操作2

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("%cn",ch);//a

int pos1=ftell(pf);
printf("%dn", pos1);//1

rewind(pf);//文件指针回到起始位置了

int pos2 = ftell(pf);
printf("%dn", pos2);//0

ch = fgetc(pf);
printf("%cn",ch);//a
fclose(pf);
pf = NULL;
return 0;
}

文件操作2

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("%dn",ch);//-1,feof(返回值-1)
fclose(pf);
pf = NULL;
return 0;
}

文件操作2

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("errorn");//读取失败结束
}
else if(feof(pf))//feof返回非0进入
{
printf("n end of filen");//遇见文件尾结束
}
fclose(pf);
pf = NULL;
return 0;
}

文件操作2

7.perror报错函数

strerror-把错误码对应的错误信息的字符串地址返回

perror:会先把你写的提示信息打印,然后再返回错误码对应的信息

int main()
{
//strerror-把错误码对应的错误信息的字符串地址返回
//printf("%sn",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;
}

留言:

到这里关于文件操作的知识就讲解完成了,希望小伙伴们多多思考练习,欢迎评论区留言讨论,收藏点赞支持一下吧!

发表评论

相关文章