写点什么

文件的使用详解

作者:lovevivi
  • 2022-10-26
    吉林
  • 本文字数:3677 字

    阅读完需:约 12 分钟

@TOC

一、文件的分类

从文件的功能考虑分为 程序文件和 数据文件程序文件包括(后缀为.c)的源程序文件,(后缀为.obj)的目标文件,(后缀为.exe)的可执行程序数据文件为程序运行时读写的数据

二、文件的打开和关闭

1.文件指针

有一个文件, 与其绑定一个文件信息区,该文件信息区可以看作是一个结构体的变量用 typedef 后 重命名为 FILE

2.文件打开


用 fopen 打开这个文件,主动创建文件信息区,将文件信息区的地址传递过来 filename 为文件名 mode 为文件的打开方式 fopen 文件打开失败会返回 NULL

(1).文件打开方式

"w"为打开文件 如果不存在这个文件 使用"w"就会自动创建一个空文件每次使用"w" , 如果文件中存在内容 就会被销毁


"r" 读文件 如果找不到文件 就会报错

2.文件关闭


stream 代表流


#include<stdio.h>int main(){ FILE*pf=fopen("text.txt","w");//打开文件 if(pf==NULL)//文件打开失败就报错 { perror("fopen"); return 1; } fclose(pf);//关闭文件 pf=NULL; return 0; }
复制代码

三、文件的顺序读写

注意事项在文件中的输入输出跟以往的不太相同输入——代表的是从文件中输入到内存中 即读取输出——代表的是从内存到文件中输出 即写入



流的概念一个高度抽象的概念正常来说 程序是需要多个转换方式到各个外部设备中 而流则作为一个转换中介的功能通过程序往流中输入数据,在通过流找到外部设备的读写方式

1.字符输出函数——fputc


写文件 c 为 字符 而返回值 int 代表 ASCII 值 stream 代表流将字符传递到流中


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main(){ FILE*pf=fopen("text.txt","w");//打开text.txt文件 以写的方式 if(pf==NULL)//判断文件是否打开失败 { perror("fopen"); return 1; } fputc('a',pf);//将字符传递到流中 foutc('b',pf); fputc('c',pf); fclose(pf);//关闭文件 pf=NULL; return 0; }
复制代码

2.字符输入函数——fgetc


读文件 sream 代表流读一个文件在一个流中如果读取正常返回字符的 ASCII 值如果读取失败返回 或者文件结束返回 EOF


关于返回类型为 int 的原因:>EOF 为文件结束标志 值为-1 字符的 ASCII 值可以当作整形计算即 返回类型为 int


#define _CRT_SECURE_NO_WARNINGS//在VS中关闭文件所要求的#include<stdio.h>int main(){ FILE*pf=fopen("test.txt","r");//从文件test.txt中读 if(pf==NULL)//假设test.txt里面为abcd { perror("fopen"); return 1; } int ret=fgetc(pf); printf("%c\n",ret);//a  ret=fgetc(pf); printf("%c\n",ret);//b  ret=fgetc(pf); printf("%c\n",ret);//c fclose(pf); pf=NULL; return 0;}
复制代码

3.文本行输出函数——fputs


写文件 string 代表字符串 sream 代表流用一行写入文件中


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main(){FILE*pf=fopen("text.txt","w");if(pf==NULL){perror("fopen");return 1;}fputs("abcdef\n",pf);fputs("qwerty\n",pf);fclose(pf);pf=NULL;return 0;}
复制代码

4.文本行输入函数——fgets


读一个字符串在流中 string 代表字符串 stream 代表流 n 代表最多读取的字符个数因为读取出来的是字符串 要加\0 故 n-1 为实际读取的字符数


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main(){FILE*pf=fopen("text.txt","r");//假设文件中为abcdefgif(pf==NULL){perror("fopen");return 1;}char arr[40={0};fgets(arr,4,pf);printf("%s\n",arr);//a b cfgets(arr,4,pf);printf("%s\n",arr);// d e f fclose(pf);pf=NULL;return 0;}
复制代码

5.格式化输出函数——fprintf


对格式化的数据 写文件 stream 代表流 format 代表格式(%s %d)


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>struct S{ char name[20]; int age; char sex[20];}int main(){struct S s={"张三",18,"男");FILE*pf=fopen("test.txt","w");if(pf==NULL){perror("fopen");return 1;}fprintf(pf,"%s %d %s",s.name,s.age,s.sex);fclose(pf);pf=NULL;return 0;}
复制代码

6.格式化输入函数——fscanf


stream 代表流 format 代表格式从文件中读取一个格式化的数据


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>struct S{ char name[20]; int age; char sex[20];}int main(){struct S s={"张三",18,"男");FILE*pf=fopen("test.txt","r");if(pf==NULL){perror("fopen");return 1;}fscanf(pf,"%s %d %s",s.name,&(s.age),s.sex);//读文件printf("%s %d %s\n",s.name,s.age,s.sex);//打印fclose(pf);pf=NULL;return 0;}
复制代码

7.二进制输出函数———fwrite


按二进制的方式写文件 buffer 指向被写的数据 size 为字节数 count 为最多写多少个元素 stream 代表流将数据的地址,字节数,元素个数 传入流中


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>struct S{ char name[20]; int age; char sex[20];}int main(){struct S s={"张三",18,"男");FILE*pf=fopen("test.txt","w");if(pf==NULL){perror("fopen");return 1;}fwirte(&s,sizeof(struct S),1,pf);fclose(pf);pf=NULL;return 0;}
复制代码

7.二进制输入函数———fread


以二进制的方式读文件从流中读取 数据的地址 字节数 元素个数返回值为实际完整读取的个数想要结束读取时 看实际读取的完整个数是否小于元素个数 为即将停止的临界


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>struct S{ char name[20]; int age; char sex[20];}int main(){struct S s={"张三",18,"男");FILE*pf=fopen("test.txt","r");//读文件if(pf==NULL){perror("fopen");return 1;}fread(&s,sizeof(struct S),1,pf);printf("%s" "%d" "%s",s.name,s.age,s.sex);打印fclose(pf);pf=NULL;return 0;}
复制代码

三、文件的随机读写

1.fseek


fseek 来判断文件指针的位置和偏移量来定位文件指针移动文件指针到特定位置 stream 代表流 offset 代表偏移量 origin 代表起始位置


关于起始位置的三种状态:SEEK_CUR 表示从当前文件指针的位置开始偏移 SEEK_END 表示从文件末尾开始偏移 SEEK_SET 表示从文件的起始位置开始偏移


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main(){ FILE*pf=fopen("text.txt","r");//这里是从已经存好数据的文件中读 if(pf==NULL)//假设文件中为abcdef { perror("fopen"); return 1; } int ret=fgetc(pf); printf("%c\n",ret);//a fseek(pf,-2,SEEK_END); ret=fgetc(pf); printf("%c\n",ret);//e  ret=fgetc(pf); printf("%c\n",ret);//f fclose(pf); pf=NULL; return 0; }
复制代码



这里要注意使用 SEEK_END 是从最后一个字符的后一个位置开始


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main(){ FILE*pf=fopen("text.txt","r");//这里是从已经存好数据的文件中读 if(pf==NULL)//假设文件中为abcdef { perror("fopen"); return 1; } int ret=fgetc(pf); printf("%c\n",ret);//a fseek(pf,2,SEEK_SET); ret=fgetc(pf); printf("%c\n",ret);//c  ret=fgetc(pf); printf("%c\n",ret);//d fclose(pff); pf=NULL; return 0; }
复制代码



SEEK_SET 从第一个字符开始


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main(){ FILE*pf=fopen("text.txt","r");//这里是从已经存好数据的文件中读 if(pf==NULL)//假设文件中为abcdef { perror("fopen"); return 1; } int ret=fgetc(pf); printf("%c\n",ret);//a fseek(pf,2,SEEK_CUR);//来到这里时已经指向b的流 所以从b开始向后2个 ret=fgetc(pf); printf("%c\n",ret);//d  ret=fgetc(pf); printf("%c\n",ret);//e fclose(pf); pf=NULL; return 0; }
复制代码

2.ftell


ftell 返回文件指针相对起始位置的偏移量 stream 代表流


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main(){ FILE*pf=fopen("text.txt","r");//这里是从已经存好数据的文件中读 if(pf==NULL)//假设文件中为abcdef { perror("fopen"); return 1; } int ret=fgetc(pf); printf("%c\n",ret);//a fseek(pf,-1,SEEK_END); ret=fgetc(pf);//f printf("%c\n",ret);//相对于起始位置的偏移量为5 fclose(pf); pf=NULL; return 0; }
复制代码

3.rewind

让文件指针位置回到文件的起始位置


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main(){ FILE*pf=fopen("text.txt","r");//这里是从已经存好数据的文件中读 if(pf==NULL)//假设文件中为abcdef { perror("fopen"); return 1; } int ret=fgetc(pf); printf("%c\n",ret);//a fseek(pf,-1,SEEK_END); rewind(pf);//文件指针回到起始位置 ret=fgetc(pf); printf("%c\n",ret);//a fclose(pf); pf=NULL; return 0; }
复制代码

四.文件读取的判定

  1. feof 函数为判断报错是 正常遇到文件尾结束 还是读取失败报错(不使用于 判断是否报错的函数)

  2. fgetc 函数 从流中读取字符 读取结束时 返回 EOF 正常情况下返回字符的 ASCII 值

  3. fgets 函数 从流中读取字符串 读取结束时 返回 NULL 正常 情况下 返回 字符串的起始地址

  4. fread 函数 二进制写文件 返回实际读取的完整元素的个数结束的临界条件为:实际读取的完整元素的个数<指定元素个数

发布于: 刚刚阅读数: 4
用户头像

lovevivi

关注

还未添加个人签名 2022-10-12 加入

还未添加个人简介

评论

发布
暂无评论
文件的使用详解_c_lovevivi_InfoQ写作社区