文件的“读”、“写”的理解不是站在“程序”的角度,而是站在“文件”的角度读:从文件中读取数据,输出到程序中写:从程序中读取数据,写入到文件中(1)在C程序中系统对文件进行的各种操作是通过指向文件结构体的指针变量实现的。定义指向文件结构欧体类型的指针变量的形式:FILE* 指针变量名;例如:  FILE  *fp1 , *fp2;
(2)文件的打开C语言文件的打开是通过stdio.h函数库的fopen()函数实现的。fopen()函数的原型是:FILE* fopen(char *filename,char *mode);其中:filename是要打开的文件的文件名,mode是说明处理文件的方式。打开文件的调用方式是:文件指针变量=fopen(文件名,处理文件方式);例如:  fopen(“a:\\exam1.c”,”r”)【如果文件不存在,造成打开文件失败】FILE *pf = fopen("a:\\exam1.c","r");if(pf==NULL) //如果返回值是NULL,则表示文件不存在,打开文件失败{cout<<"文件不存在,打开文件失败"<<endl;exit(-1);  //exit(0)表示正常退出,exit(非0)表示程序出错后退出}
(3)文件的读写操作(当文件打开后,最常见的操作就是对文件的读取和写入操作)
下面介绍四种常用的文件的读取和写入操作的函数从文件读取   |  向文件写入①按  字符  读写的函数: fgetc()    |  fputc()     读写“一个”字符②按  字符串读写的函数: fgets()     |  fputs()③按格式要求读写的函数: fprintf()   |  fscanf()④按  数据块读写的函数: fread()     |  fwrite()
上面常见的四种函数功能介绍以及应用举例
①fgetc()    |  fputc()
调用形式:fgetc(文件型指针类型)  例:char ch = fgetc(fp);//作用:从一个文件中读取一个字符//返回值:返回所读取的一个字节。如果读到文件末尾或者读取出错时返回EOF。
调用形式:fputc(字符,文件型指针类型);  例:fputc('A',fp);//执行过程:将字符‘A’(也可以是字符型变量)写入文件的当前位置,并且使指向文件当前位置的指针下移一个字节。//返回值:如果写入成功,返回的是该字符的ASCII值; 如果写入失败,返回EOF
②fgets()     |  fputs()
调用形式:char* fgets(字符数组,字符数,文件型指针变量);  char *fgets(char *buf, int bufsize, FILE *stream);//作用:从fp指向的文件的当前位置读取n-1个字符,再加上字符串结束标记'\0'(注意:字符串的结束标志‘\0’不写入文件中去),一起放入字符数组中。
特殊情况:fgets函数一旦遇到字符'\n',就会在'\n'后面加上字符串结束字符'\0',然后把之前读入包括'\n'和'\0'的字符数组存放到buf中//返回值:函数成功将返回字符数组的首地址; 失败或读到文件结尾返回NULL。
//【分析】如果开辟的buf过大,则不会出现任何问题,但是会浪费内存空间;但是如果开辟的buf过小,会导致。见下面例子:
假设文件中有下面两行字符串:
Love,I Have
Since you can do it.
//先用fgets(str1,6,file1);去读取,则读取后 str1 = “Love,\0”
//再执行fgets(str1,20,file1);去读取:此时从I开始读取,读取19个字节,但是由于提前遇到'\n'字符,会在'\n'后面加上'\0',因此读取后结果str1 = " I Have\n"
因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判断。调用形式:int fputs(const char* str,FILE* fpout);【使用实例1】
#include <stdio.h>
#define LENGTH 100
int main(void)
{  FILE *fd;  char str[LENGTH];  //创建一个文件  fd = fopen("hello.txt","w+");  //往文件里面写入字符串“"hello.world"  if(fd)  {  fputs("hello,world",fd);  } //关闭文件  fclose(fd);  //再次打开文件,并读出所有字符串  fopen("hello.txt","r");  fgets(str,LENGTH,fd);  //输出到标准输出设备  printf("%s\n",str);  //关闭文件  fclose(fd);
}
【使用实例2】   将文件d:\data1.txt中的内容复制到d:\data2.txt中。
{FILE *f_in, *f_out;   char str[50];f_out = fopen(“d:\\data1.txt”,"r");  //读取f_in  = fopen(“d:\\data2.txt”,"w");   //写入…… …… ……while(!feof(f_out))   //如果f_out遇到的不是字符串结束标志,则进入while循环{fgets(str,30,f_out); //f_out读取30个字符赋值给strfputs(str,f_in);     //把str写入到f_in打开的文件中}fclose(f_out);   fclose(f_in);
}
③fprintf()   |  fscanf()
调用形式:int fprintf(文件型指针变量, 格式控制, 输出表列);
//解释:函数fprintf()的作用与printf()相类似,只是输出对象不是“标准输出设备”而是“文件”,即按照格式要求“将数据写入文件”。
例如:  fprintf(fp,"%ld,%s,%5.1f",num,name,score);//作用:将变量num、name、score按照%ld、%s、%5.1f的格式写入fp指向的文件的当前位置调用形式:int fscanf(FILE* stream, const char* format, [argument...]);翻译成int fscanf(文件型指针变量, 格式控制, 输出表列);例: /*从文件中读取数据*/fscanf(stream,"%s",s);fscanf(stream,"%ld",&l);  //和scanf对比相类似,输出表列的变量加上 &fscanf(stream,"%f",&fp);fscanf(stream,"%c",&c);④按数据块读写的函数fread()、fwrite()
调用形式:size_t  fread( void *buffer, size_t size, size_t count, FILE *stream) ;
buffer  buffer是一个变量,它用于存放从stream中读取到的数据.
size    要读的每个数据项的字节数,单位是字节byte.
count   要读count个数据项,每个数据项size个字节.
stream  输入流.
//作用:作用是从文件中读出成批的数据块。即:fread是一个函数。从一个文件流中读数据,最多读取//count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回 0。
//返回值:如果函数fread()操作成功,则返回值为实际从文件中读取数据块的个数。调用形式:fwrite(写入文件的数据块的“存放地址”,一个数据块所占的字节数,数据块的个数,文件型指针变量);size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);//返回值是:写入数据块的个数(次数),因此由返回值可以判断是否读取到值!,见下面示例:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
struct stu
{int age;char ch[100];
}st[3]={{20,"Tom"},{21,"Mary"},{23,"Faker"}};int main()
{FILE *fp = fopen("D.txt","w+");if(!fp){printf("打开失败\n");exit(-1);}//方式一://while(fwrite(&st[0],sizeof(struct stu),3,fp) != 3)//{//}int count = fwrite(&st[0],sizeof(struct stu),  3,fp); //正确,因为st[]数组的大小就是3.//int count = fwrite(&st[0],sizeof(struct stu),300,fp); //错误,从st[]数组中读取数据时,会发生越界//方式二:读结构体数组时最好用方式二,逐个读取st[i]//for(int i=0;i<3;i++)//{//  if(fwrite(&st[i],sizeof(struct stu),1,fp) !=1 ) //第三个参数是1,表示一次读取一个st[i]//  {//      printf("写入失败,退出程序\n");//      exit(-1);//  }//}return 0;
}buffer:是一个指针,与fread(“存取数据的地址”)中不同,对fwrite来说,是要 “获取数据的地址”,例如buffer中存放着很多数据,把buffer中的数据写到stream打开的文件夹中。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
struct stu
{int age;char ch[100];
}st[3];int main()
{//为了验证上面fwrite是否把结构体数组中存放的数据写入到文件C.txt中去,///我们可以用下面的程序进行测试:用一个文件指针fp以“r”的方式打开文件,///把读取到的数据存放到&st[i]中,然后把是st[i]中的数据输出,看下///输出结果是不是上面fwrite写入的数据?如果是,表明写入成功;如果不是,///表明写入失败。FILE *fp = fopen("C.txt","r+");if(!fp){printf("打开失败\n");exit(-1);}方式一://  if(fread(&st[0],sizeof(struct stu),3,fp) !=3 ) //第三个参数是3,一次读取3个st[i]//  {//      printf("写入失败,退出程序\n");//      exit(-1);//  }//  for(int i=0;i<3;i++)//  {//      printf("%5d,%s\n",st[i].age,st[i].ch);//  }//方式二   for(int i=0;i<3;i++){if(fread(&st[i],sizeof(struct stu),1,fp) !=1 ){printf("写入失败,退出程序\n");exit(-1);}printf("%5d,%s\n",st[i].age,st[i].ch);}return 0;
}
【fread简单示例】
例如:已知stu1是一个结构体struct student变量,则
fread(&stu1, sizeof(struct student ), 1, fp);
表示的含义是从文件类型指针fp指向的文件的当前位置开始,读取1个数据块,该数
据块为结构体struct student类型变量所占字节数,然后将读取的内容放入变量stu1中。
【fwrite简单示例】例如:已知struct student 类型的数组stu[20],则语句fwrite(&stu[1], sizeof(struct student ), 2, fp);
表示的含义是 ——> 从结构体数组元素stu[1]存放的地址开始,以一个结构体struct student类型变量所占字节数为一个数据块,共写入文件类型指针fp指向的文件2个数据块,即stu[1]、stu[2]的内容写入文件。如果操作成功,函数的返回值为2。【fread、fwrite综合示例1】创建一个文件并写入一段数据,然后读取出来。
#include <stdio.h>void main( void )
{FILE *stream;char list[30];int i, numread, numwritten;// 以文本方式打开文件if( (stream = fopen( "fread.out", "w+t" )) != NULL )  // 如果读取无误{for ( i = 0; i < 25; i++ )  //给list[i]数组的每个元素进行赋值list[i] = (char)('z' - i);//fwrite:从list数组中获取字符,要写入大小为sizeof(char)的字符,一共写入25次,写到stream打开的文件中,返回值是实际写入的次数numwritten = fwrite( list, sizeof( char ), 25, stream );printf( "Wrote %d items\n", numwritten );fclose( stream );}else{printf( "Problem opening the file\n" );}if( (stream = fopen( "fread.out", "r+t" )) != NULL )  // 文件读取{numread = fread( list, sizeof( char ), 25, stream );printf( "Number of items read = %d\n", numread );printf( "Contents of buffer = %.25s\n", list );fclose( stream );}else{printf( "File could not be opened\n" );}
}
运行结果:Wrote 25 itemsNumber of items read =25Contents of buffer = zyxwvutsrqponmlkjihgfedcb【fread、fwrite综合示例2】将10个学生记录输入文件d:\stu中,然后显示。
struct ST
{char class[6];…………
}a[N],stu;  //定义一个结构体数组a[N]和结构体变量stuint main()
{int i;   FILE *fp = fopen("d:\\stu","wb"); //写入方式打开文件夹for(i=0;i<N;i++) //给结构体数组a[N]中的每个元素输入数据{printf("\n\t请输入班级:"); scanf("%s",a[i].class);…… ……  ……    }if(fwrite(a,sizeof(struct ST),N,fp)!=N)  //用fwrite函数写入往fp打开的文件中写入大小为sizeof(struct ST),个数为N的数据{//如果fwrite返回的值不等于Nprintf("文件不能写入数据.\n");//那么,打印这句话 exit(1);  //异常退出}fclose(fp);//关闭fp打开的文件夹,此时fp已经不指向之前打开的文件夹fp=fopen("d:\\stu","rb");  //以读取方式打开 “上面刚写入数据的文件夹d:\\stu” for(i=0;i<N;i++){ if(fread(&stu,sizeof(struct ST),1,fp)= =1) //从fp打开的文件读取1个以stu的地址为起始地址,大小为sizeof(struct ST),个数为1的数据,存放到&stu中去printf("\t%6s%10ld%9s%5d%6d%8d\n",stu.class,… … … );//printf在屏幕上格式化输出else  //如果返回值不是1{printf("文件不能读取数据.\n");  exit(1); //则异常退出}}fclose(fp);
}(4)文件的关闭(当文件操作结束后,为了防止误操作等操作破坏打开的文件,应该在使用后及时的关闭)具体做法:fclose(文件指针fp);  //则将fp指向的文件关闭,fp不在指向之前被打开的文件【拓展】文件中常用的函数 fseek()、feof()、rewind()、ftell()fseek():int fseek(FILE *stream, long offset, int fromwhere);等价于fseek(文件型指针变量,偏移量,起始位置);
/*int fseek( FILE *stream, long offset, int origin);
第一个参数stream为文件指针
第二个参数offset为偏移量,正数表示正向偏移,负数表示负向偏移第三个参数origin设定从文件的哪里开始偏移,可能取值为: SEEK_SET、SEEK_CUR、 SEEK_END
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END依次为0,1和2.
简言之:
fseek(fp,100L,0);把stream指针移动到离文件开头100字节处;
fseek(fp,100L,1);把stream指针移动到离文件当前位置100字节处;
fseek(fp,-100L,2);把stream指针退回到离文件结尾100字节处。
*/
函数设置文件指针stream的位置:如果执行成功,stream将指向以fromwhere为基准,偏移offset(指针偏移量)个字节的位置,函数返回0。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置,函数返回一个非0值。feof():用来检测一个指向文件的指针是否已经指到了文件最后的结束标志EOF。调用的一般形式为:  feof(文件型指针变量);如果文件型指针指向的文件的当前位置为结束标志EOF,则函数返回一个非零值,否则返回0值。
rewind():将令指向文件的指针重新指向文件的开始位置。函数无返回值。其调用形式为:   rewind(文件型指针变量);例如: rewind(fp);//fp是一个指向文件的指针,执行该语句后,fp指向文件的开始位置,即文件的第一个数据。
ftell():用于测试指向文件的指针的当前位置。调用方式为:      ftell(文件型指针变量);//函数的返回值是一个常整型数,如果测试成功,则返回指向文件的指针当前指向的位置距离文件开头的字节数,否则返回-1L #include "stdio.h"
#include "stdlib.h"
#include "string.h"
int main()
{//按字符FILE *fp = fopen("A.txt","a+"); //a+表示追加char ch[] = "ABCDDCBA";int i=0;while(ch[i]!='\0'){if(fputc(ch[i],fp)==0){printf("func:fput error");exit(-1);}i++;}fclose(fp);getchar();
}
int main()
{//按行FILE *fp = NULL;char *filename = "code.txt"; if((fp = fopen(filename,"r"))==NULL) //“r”打开文件{printf("func:fopen() err\n");return 0;}char ch[300];memset(ch,0,sizeof(char)*300);
//从fp打开的文件中读取数据,显示到窗口中有以下两种方式
//方式一//while(fgets(ch,300,fp)) //逐行读取fp打开的文件,把读到的数据存放到ch[]中//{//  printf("%s\n",ch);//注意:此时自己加上字符 '\n'//  memset(ch,0,sizeof(char)*300);//}
//方式二:(这种方式比方式一好!)while(!feof(fp))  //此处是!feof(fp),不要忘记感叹号'!'{fgets(ch,300,fp); //逐行读取fp打开的文件,把读到的数据存放到ch[]中printf("%s\n",ch);memset(ch,0,sizeof(char)*300);}fclose(fp);getchar();
}【总结】文件操作
1、C语言文件读写概念建立以及文件读写API的熟悉
API的种类
一、文件读写APIfgetc    fgetc  按照字符读写文件fputs    fgets  按照行读写文件(读写配置文件)fread    fwrite 按照块读写文件(大数据块迁移)fprintf  fscanf 按照格式化读写文件二、文件控制API文件是否结束文件指针的定位、跳转
三、用API做项目
2、项目开发,配置文件读写库的设计与实现
3、项目开发:大数据文件加密解密设计与实现

第五天2017/04/06(上午:文件的“读写操作”)相关推荐

  1. 第五天2017/04/06(下午2:动态链接库(DLL))

    创建动态库:新建一个DLL的VS工程,选择"空项目",此时会进入到新建的项目工程中:在项目工程中添加.h..c..cpp文件,并且填写代码:编译运行,在Debug下生成.dll和. ...

  2. 第五天2017/04/06(下午3:静态链接库(Lib))

    原文链接:http://blog.csdn.net/xiaoding133/article/details/8973436 一.静态链接库和动态链接库 1.静态链接库(.LIB):函数和数据被编译进一 ...

  3. 第五天2017/04/06(下午1:C、C++混合编程 与 #ifdef __cplusplus extern C{ })

    C++.C编译器对函数编译的相关知识:C++支持函数重载,而C不支持,两者的编译规则也不一样.函数被C++编译后在符号库中的名字与C语言的不同.例如,假设某个函数的原型为: void foo( int ...

  4. python学习的第二十五天:对PDF文件的读写操作

    文章目录 python学习的第二十五天:对PDF文件的读写操作 对Excel操作的补充 python的实用方法 获取指定文件下的所有内容 shutil模块(封装了高级的文件操作函数) PDF的相关操作 ...

  5. python3 读取文本文件_python3文件的读写操作

    open函数:对文件进行读写操作前,先打开文件,获取文件的句柄: open(file, mode, encoding, buffering) 参数说明 file_name:一个包含了你要访问的文件路径 ...

  6. Python小练习1:.txt文件常用读写操作

    .txt文件常用读写操作 本文通过一个实例来介绍读写txt文件的各种常用操作,问题修改自coursera上南京大学的课程:用Python玩转数据. 直接进入正题,考虑下面为练习读写txt文件的各种操作 ...

  7. java 二进制 文件比较_Java中对文件的读写操作之比较

    Java 中对文件的读写操作之比较 作者:Jeru Liu 日期:November 29,2000 版本:1.0 纪念在chinaasp积分过一百呕心原创一篇(Java 中对文件的读写操作之比较)拿分 ...

  8. python文件下载速度 装饰器_python使用装饰器对文件进行读写操作'及遍历文件目录...

    '''使用装饰器对文件进行读写操作''' #def check_permission(func):#'''演示嵌套函数定义及使用'''#def wrapper(*args,**kwargs):#''' ...

  9. 文件的读写操作 c# 1614992256

    文件的读写操作 c# 1614992256 读操作 写操作

最新文章

  1. 以太坊开发 发行代币的增发功能 并实现转到钱包 和买卖的功能
  2. 腾讯数十亿广告的基础是精准实时推荐
  3. 近世代数--整环--高斯整环
  4. 科大星云诗社动态20220101
  5. Pytorch模型(.pth)转onnx模型(.onnx)
  6. 若依部署上线之后验证码不显示的解决方法之一
  7. 【渝粤题库】广东开放大学 商务交际听说 形成性考核
  8. 正确理解Python函数是第一类对象
  9. 在浏览器里友好的变量输出查看函数方法
  10. ssh免密码远程执行sudo命令
  11. GitLab 内置了 CI/CD 工具,强大啊!!
  12. 唐宇迪学习笔记2:Python数据分析处理库——pandas
  13. PyCharm自定义背景图片、更换主题
  14. 关于CS模式和P2P模式分发文件速度的思考
  15. Tegra TX1 build tensorflow r1.1
  16. HC32F460 SPI DMA 驱动 TFT显示屏
  17. 精美卡通儿童教育班会课件PPT模板
  18. 关于Smartphone的智能手机键盘输入法的疑惑
  19. idea2022报错: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
  20. IST改进算法之Two-Step Iterative Shrinkage/Thresholding(TwIST)

热门文章

  1. 超有用的,从此vi变得友好了
  2. spring security源码分析之core包
  3. mysql --The MEMORY Storage Engine--官方文档
  4. MySQL——单表查询练习:彩票数据核对
  5. 【风控建模】风控分类模型种类(决策、排序)比较与模型评估体系(ROC/gini/KS/lift)
  6. 进程间通信的5种方式
  7. 用Kubernetes部署超级账本Fabric的区块链即服务(1)
  8. 利用Facebook开源项目来赚钱不再只是梦
  9. 斐波那契数列递归解法
  10. SpringBoot - 优雅的实现【参数校验】高级进阶