第十一章 文件操作 文件的概念 文件的读写 主讲:李祥 时间:2015年10月.

Slides:



Advertisements
Similar presentations
C 语言程序设计 文件 周闻钧 朱宏明.
Advertisements

C程序设计 第10章 文 件 主讲教师: 鲁 萍 西安建筑科技大学 理学院.
第十三章 文件.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
目标 运用File类进行文件操作 理解流,标准输入/输出流的概念
在PHP和MYSQL中实现完美的中文显示
第12章 文 件 §12.1 概述 1.文件信息的集合,如一段程序、一段数据、一副图等
複習 struct score_Type{ int chinese,english; }; struct my_Type{
C File System.
第8章 文件 P 了解文件的处理过程 8.2 掌握文件的基本操作本领 8.3 文件的应用举例 *贯穿教学全过程的实例.
Hadoop I/O By ShiChaojie.
计算概论 第二十一讲 文件操作 北京大学信息学院.
第10章 文件操作.
第十一章 文件 文件概述 文件操作 文件操作实例 本章小结 作业: 练习:
第10章 文件.
第10章 文件操作.
C 程式設計— 檔案處理 台大資訊工程學系 資訊系統訓練班.
11.1 文件的基本概念 11.2 文件的打开与关闭 11.3 文件的顺序读写 11.4 文件的随机读写 11.5 文件检测
走进编程 程序的顺序结构(二).
辅导课程六.
函数申明、定义、调用 申明: void sort(float a[], int n); void sort(float *a, int m); void sort(float *a, int); void sort(float *, int);
第十二章 文件 12.1 C文件概述 文件:存储在外部介质上数据的集合,是操作系统数据管理的单位 文件分类 按文件的逻辑结构: 按存储介质:
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
fp=fopen("CD2.dat","wb"); fwrite(&min,8,1,fp); fclose(fp);
程式設計 博碩文化出版發行.
第九章 文件 程序数据标准输入输出设备 程序数据文件 数据流和文件 文件的打开和关闭 文件读写函数.
File(檔案處理) 學習目標:開檔、讀檔、更新檔與關閉檔案.
THE C PROGRAMMING LANGUAGE
第10章 文件操作.
本节内容 模拟线程切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
如何生成设备节点 广州创龙电子科技有限公司
第十章 文件操作.
第10章 对文件的输入输出 10.1 C文件的有关基本知识 10.2 打开与关闭文件 10.3 顺序读写数据文件 10.4 随机读写数据文件
第10章 檔案與資料夾處理 10-1 C語言的檔案輸入與輸出 10-2 文字檔案的讀寫 10-3 二進位檔案的讀寫
第十三章 文件 目录 学生信息管理系统的完善 文件的概念 文件类型指针 文件的打开与关闭 文件的顺序读写
第9章 文件 本章导读 本章主要知识点 《 C语言程序设计》 (Visual C++ 6.0环境)
第5章 文件.
第9章 文件操作 文件 使用文件的目的 操作系统管理数据的基本单位 存储在外存储器上的数据的集合
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
研讨课4 文件操作.
目录 11.1 文件的种类 11.2 文件指针和文件内部的位置指针 11.3 文件的操作 11.4 文件的打开与关闭
第十三章 文件.
Java语言程序设计 清华大学出版社 第8章 输入输出流(1).
第9章 文件 学习目的与要求: 熟练掌握文件指针的使用 掌握与文件相关的函数 能够利用文件相关函数实现各种操作.
C语言程序设计.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
一、文件的基本概念 第十三章 文 件 所谓“文件”是指一组相关数据的有序集合。 这个数据集有一
C程序设计.
本节内容 随机读取 视频提供:昆山爱达人信息技术有限公司.
實習十 開讀檔練習.
<编程达人入门课程> 本节内容 内存的使用 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群: ,
C標準輸出入函數庫 與 作業系統.
第九节 赋值运算符和赋值表达式.
3.16 枚举算法及其程序实现 ——数组的作用.
本节内容 结构体 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
函数申明、定义、调用 申明: void sort(float a[], int n); void sort(float *a, int m); void sort(float *a, int); void sort(float *, int);
本节内容 文件系统 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第13章 文 件.
_08文件操作 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
C 程式設計— 檔案處理 台大資訊工程學系 資訊系統訓練班.
結構、檔案處理(Structure, File)
第13章 文 件 六、字符和字符串读写函数 七、无格式转换的读写函数fread和fwrite 八、文件的定位 九、一个简单的读写存盘程序步骤.
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第七章 文件 7.1 文件的基本概念 7.2 文件类型指针 7.3 文件的打开与关闭 7.4 文件的读/写 7.5 文件的随机读/写
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
C语言程序设计 第13章 文件操作.
Presentation transcript:

第十一章 文件操作 文件的概念 文件的读写 主讲:李祥 时间:2015年10月

11.1 文件概述 11.2 文件的打开与关闭 11.3 文件的读写 11.4 文件的随机读写

11.1 文件概述 11.1.1 文件 现实生活中经常会使用电脑记录一些信息,这些信息都是以文件的形式存储在磁盘上。下面就来看一下第一章中用C语言编写的程序文件,打开D:\itcast\chapter01\Program01目录,其中内容如图11-1所示。 图11-1 文件目录

11.1 文件概述 11.1.1 文件 图11-1所示的Program01目录下除了Debug是文件夹,其余三个都属于文件。 在C语言中,根据文件的存储形式,可分为文本文件和二进制文件,下面将针对这两种文件在内存中的存储形式进行分析,具体如下:

11.1 文件概述 11.1.1 文件 1、文本文件 在文本文件中数据是以字符形式呈现的,每个字符占用一个字节,而字节在计算机中又是以ASCII码来识别。在存储文本文件时需要先将ASCII码值转换为二进制的形式然后进行存储。 例如,在内存中将整数123以文本形式存放,如图11-2所示。 图11-2 文本文件存放形式

11.1 文件概述 11.1.1 文件 在图11-2中,由于文本形式存储的数据都是以字符形式展示的,所以整数123被拆分为三个字符‘1’、‘2’、‘3’。这三个字符所对应的ASCII码值分别为49、50、51,长方形内的数字是该ASCII码对应的二进制数,每一个二进制数表示一个字节。

11.1 文件概述 11.1.1 文件 2、二进制文件 二进制文件在存储数据时是直接以二进制的方式进行的,这种存储方式与数据在内存中的存储方式相同,不需要进行转换。因此不仅可以提高执行效率,还能节省存储空间。 例如,在内存中将整数123以二进制形式存放,如图11-3所示。 图11-3 二进制存放形式

11.1 文件概述 11.1.1 文件 在图11-3中,整数123在内存中是以二进制数“00000000 01111011”直接存储的,所以将二进制文件从硬盘中读取到内存时不需要数据转换。

11.1 文件概述 11.1.2 文件指针 文件指针是一个指向文件有关信息的指针,这些信息包括文件名、状态和当前位置,它们保存在一个结构体变量中。在使用文件时需要在内存中为其分配空间,用来存放文件的基本信息。该结构体类型是由系统定义的,C语言中规定该类型为FILE,其声明方式如下: typedef struct { int filename; //文件名 int mode; //文件操作模式 char *next; //下一个字符位置 } FILE;

11.1 文件概述 11.1.2 文件指针 上述代码中使用typedef关键字定义了一个变量名为FILE的结构体类型,在编写程序时可直接使用上面定义的FILE类型来定义变量,注意在定义变量时不必将结构体内容全部给出,只需写成如下形式: 其中,fp是一个指向文件的指针。当使用它指向test.txt文件时,可以使用以下代码: FILE * fp; fp = fopen("test.txt","r");

11.1 文件概述 11.1.2 文件指针 上述代码表示通过fopen()函数打开test.txt文件,并使用一个指针变量fp指向该文件,在C语言中操作文件时都需要使用文件指针而不是文件名。

11.1 文件概述 11.1.3 文件位置指针 为了对文件读写进行控制,系统为每个文件设置了一个位置指针,该指针被称为文件位置指针,用来标识当前文件的读写位置。 一般在对字符文件进行顺序读取操作时,文件的位置指针指向文件开头。当对文件进行读取操作时,首先读取第一个字符,然后文件的位置指针按顺序向后移一个位置,在下一次执行读取操作时,将指针指向的第二个字符。以此类推,一直读取到文件末尾结束。为了让读者更好的理解文件的读取过程,接下来通过一个图例进行描述,如图11-4所示。

11.1 文件概述 11.1.3 文件位置指针 图11-4 文件位置指针 如果是顺序写文件,则每写完一个数据后,文件的位置指针自动按顺序向后移一个位置,然后在下一次执行写操作时,把数据写入指针所指的位置。直到数据全部写完,此时位置指针在最后一个数据之后。有时希望在一个文件的原有数据之后再添加新的数据,应该把文件位置指针移到文件末尾,然后再接着写入新的数据,这就是文件的追加。

11.1 文件概述 11.1.3 文件位置指针 需要注意的是,在读写的过程中,也可以人为的移动文件指针的位置,进行文件的随机读写操作。例如将指针向前移向后移,移到文件头或文件尾,然后对该位置的内容进行读写。关于随机读写文件的内容将在11.4节中进行详细的讲解。

11.1 文件概述 11.1.4 流 大多数应用程序都需要实现与设备之间的数据传输,例如,键盘可以输入数据、显示器可以显示程序的运行结果等,在C语言中将这种通过不同输入/输出设备(键盘、内存、显示器、网络等)之间的数据传输抽象表述为“流”。流实际上就是一个字节序列,输入程序的字节序列被称为输入流,从程序输出的字节序列被称为输出流。为了方便读者更好的理解流的概念,可以把输入流和输出流比作两根“水管”,如图11-5所示。

11.1 文件概述 11.1.4 流 图11-5 输入流和输出流 图11-5中,输入流被看成一个输入管道,输出流被看成一个输出管道,数据通过输入流从源设备输入到程序,通过输出流从程序输出到目标设备,从而实现数据的传输。

11.1 文件概述 11.1.4 流 1、文本流和二进制流 2、预定义的流 输入输出流还可以进一步细分为,文本流(字符流)和二进制流。它们之间的主要差异是,在文本流中输入输出的数据是一系列的字符,可以被修改。在二进制流中输入输出数据是一系列字节,不能以任何方式修改。 2、预定义的流 C语言中有三个系统预定义的流,分别为标准输入流(stdin,全称standard input)、标准输出流(stdout,全称standard output)和标准错误输出流(stderr,全称standard error)。这三个标准流分别对应于键盘上的输入、控制台上的正常输出和控制台上的错误输出。它们都是在stdio.h头文件中预定义的,程序只要包含这个头文件,在程序开始执行时,这些流将自动被打开,程序结束后,则自动关闭,不需要做任何初始化准备。

11.2 文件的打开与关闭 在操作硬盘上的一个文件时,首先要打开文件,再对文件的内容进行浏览或修改,使用完该文件后需要关闭文件。同理,在程序中要想使用文件也需要打开和关闭文件。本节将分别讲解如何在程序中打开和关闭文件。 1、打开文件 在C语言提供了一个fopen()函数,该函数用于打开文件,其返回值类型为文件指针。fopen()函数的语法格式如下: FILE* fopen(char* filename, char* mode);

11.2 文件的打开与关闭 上述语法格式中,FILE *表示该函数返回值为文件指针类型,fopen是打开文件函数的名称。fopen()函数包含两个参数,第一个参数filename用于指定文件的全路径,即包含路径名和文件的扩展名,第二个参数mode用于指定文件的打开模式。 文件打开模式就是指以哪种形式打开文件,例如只读模式、只写模式都是文件的打开模式,具体如表11-1所示。

11.2 文件的打开与关闭 表11-1列举了文件的所有打开模式,对于读者来说只需了解即可,在后面的案例中会演示这些模式的用法。 表11-1 文件打开模式 表11-1列举了文件的所有打开模式,对于读者来说只需了解即可,在后面的案例中会演示这些模式的用法。 打开模式 名称 描述 r 只读模式 打开文件,只允许读取数据,目标文件必须存在。 w 只写模式 打开文件,只允许写入数据,若目标文件已存在,则覆盖原文件,否则创建新文件。 a 追加模式 打开文件,只允许追加数据(在文件末尾写入),若目标文件已存在,则覆盖原文件,否则创建新文件。 r+ 读取/更新模式 打开文件,可以进行读取和写入操作,但目标文件必须存在。 w+ 写入/更新模式 打开文件,可以进行读取和写入操作,若目标文件已存在,则覆盖原文件,否则创建新文件。 a+ 追加/更新模式 打开文件,允许读取和追加数据,若目标文件已存在,则覆盖原文件,否则创建新文件。

11.2 文件的打开与关闭 2、关闭文件 在C语言提供了一个fclose()函数,该函数用于关闭文件,其返回值int类型。fclose()函数的语法格式如下: 上述代码中fclose()函数将文件指针作为参数,返回int类型的值。如果成功关闭文件就返回0,否则返回EOF。需要注意的是,EOF是一个特殊的字符,是英文“end of file”的缩写,被称为文件结束字符,该字符是在stdio.h头文件中定义的,通常表示不能再从流中获取数据。 int fclose(FILE* p);

11.2 文件的打开与关闭 学习完文件的打开和关闭操作后,就可以开始对文件的具体操作进行学习了。接下来通过一个简单案例来学习一下文件的打开关闭操作,如例11-1所示。 例11-1 1 #include <stdio.h> 2 void main() 3 { 4 FILE* fp; //定义文件指针变量 5 fp = fopen("hello.txt", "w"); //打开文件,若文件不存在则创建 6 if (fp == NULL) //如果文件打开失败 7 { 8 printf("无法打开hello.txt\n"); 9 return -1; 10 } 11 fputs("Hello, world!\n", fp); //向文件中写入一个字符串 12 fclose(fp); //关闭当前文件 13 printf("文件写入成功\n"); 14 }

11.2 文件的打开与关闭 运行结果如图11-6所示。 图11-6 运行结果 在例11-1中,首先定义一个文件指针变量fp,然后使用fopen()函数打开hello.txt文件,通过fputs()函数向该文件写入“Hello, world”,写入完成后需要使用fclose()函数关闭fp所指向的文件。这里读者只需要知道fputs()函数表示向文件中写入一个字符串即可,后面将对其进行详细地讲解。

11.2 文件的打开与关闭 程序运行成功后,会在当前项目根目录下生成一个hello.txt文件,打开文件,其内容如图11-7所示。 图11-7 运行结果 需要注意的是,mode参数为char*类型,但在实际开发过程中必须使用字符串的形式,如果将“w”写成‘w’就会造成程序出现错误。

11.3 文件的读写 11.3.1 单字符读写文件 在C语言中,针对文件读写提供了fgetc()和fputc()函数,这两个函数都是针对字符进行读写操作的。下面就分别来学习一下这两个函数的使用。 1、使用fputc()函数向文件写入字符 fputc()函数用于向文件中写入一个字符,其语法格式如下: 在上述语法格式中,ch表示写入的内容,fp表示一个文件指针,int表示函数返回值的类型为整数类型。接下来通过一个具体案例来学习一下fputc()函数的使用,如例11-2所示。 int fputc(char ch, FILE* fp);

11.3 文件的读写 11.3.1 单字符读写文件 例11-2 include <stdio.h> void main() { FILE *fp; int i=0; char arr[]="I Like C Program"; fp = fopen("hello.txt", "w"); //打开一个文件,若文件不存在创建文件 if (fp == NULL) //文件不存在,则输出提示信息 printf("打开文件失败!\n"); return -1; } while (arr[i]!='\0') fputc(arr[i], fp); i++; fclose(fp);

11.3 文件的读写 11.3.1 单字符读写文件 例11-2运行成功后,在根目录打开hello.txt文件,可以看到该文件中的内容如图11-8所示。 图11-8 运行结果 从图11-8中可以看出,字符串被成功写入文件中了。在程序中首先定义一个字符数组并以只写的方式打开hello.txt文件,然后通过while循环遍历字符数组将数组中的字符通过fputc()函数写入到文件中,最后调用fclose()函数关闭文件。

11.3 文件的读写 11.3.1 单字符读写文件 2、使用fgetc()函数读取文件中的字符 在上述语法格式中,参数fp表示一个文件指针变量,char表示函数返回值的类型为字符类型。接下来通过一个具体案例来学习一下fgetc()函数读取例11-2中的hello.txt内容,如例11-3所示。 char fgetc(FILE* fp);

11.3 文件的读写 11.3.1 单字符读写文件 例11-3 1 #include <stdio.h> 2 void main() 3 { 4 FILE *fp; 5 int i=0; 6 char ch; 7 fp = fopen("hello.txt", "r"); 8 if (fp == NULL) 9 { 10 printf("打开文件失败!\n"); 11 return -1; 12 } 13 ch = fgetc(fp); //从文件中读取每个字符 14 while (ch != EOF) 15 { 16 printf("%c", ch); 17 ch = fgetc(fp); 18 } 19 printf("\n"); 20 fclose(fp); 21 }

11.3 文件的读写 11.3.1 单字符读写文件 运行结果如图11-9所示。 图11-9 运行结果 从图11-9中可以看出,文件hello.txt中的内容被读取成功了。在程序中首先定义了一个文件指针并以只读的方式打开文件,然后通过while循环依次调用fgetc()函数读取文件中的一个字符并输出至控制台,最后调用fclose()函数关闭文件。

11.3 文件的读写 11.3.1 单字符读写文件 多学一招:文件的统计操作 在实际工作中,经常会遇到统计文件内容的需求,如单词数目、数字数目、标点符号数目等。在C语言中,可以通过遍历文件中的每个字符,并判断字符类型来实现统计的功能。接下来通过一个案例来演示统计文件中数字的个数,如例11-4所示。

11.3 文件的读写 11.3.1 单字符读写文件 例11-4 1 #include <stdio.h> 2 void main() 3 { 4 char filename[255]; //定义字符数组用于存放输入的文件路径名 5 FILE* fp; //定义一个文件指针fp 6 char ch; 7 long digits = 0; //定义一个长整型变量用于记录统计的数字个数 8 printf("请输出待统计文件的路径:"); 9 scanf("%s", filename); 10 fp = fopen(filename, "r"); //以只读模式打开输入的路径文件 11 if(fp == NULL) 12 { 13 printf("打开文件时发生错误。\n"); 14 return -1; 15 } 16 ch = fgetc(fp); //获取文件中的一个字符 17 while (ch != EOF) //如果文件没有读取完毕继续执行 18 { 19 if (ch >= '0' && ch <= '9') //如果获取字符为数字,变量digits加1 20 { 21 ++digits; 22 } 23 ch = fgetc(fp); 24 } 25 printf("统计结束。\n"); 26 printf("文件中有%ld 个数字。\n", digits); 27 }

11.3 文件的读写 11.3.1 单字符读写文件 运行程序,输入“D:\itcast\chapter09\itcast.txt”文件的路径后,结果如图11-10所示。 图11-10 运行结果 从图11-10中可以看出,文件中包含了13个数字,接下来打开itcast.txt文件验证一下统计是否正确,文件内容如图11-11所示。

11.3 文件的读写 11.3.1 单字符读写文件 图11-11 运行结果 从图11-11中可以看出,文件中确实包含了13个数字,这与程序输出结果是一致的。需要注意的是,在程序中,使用long型变量存储次数时,一定要为该变量设置初始值。

11.3 文件的读写 11.3.2 单行读写文件 在上一节中讲解了如何逐一字符对文件进行读写操作,当处理文件的数据量较大时,这样的做法效率非常差。为了提高效率,在C语言中还提供了fgets()和fputs()函数,这两个函数可以实现按行或按固定长度对文件进行读写操作,下面结合案例来学习这两个函数。

11.3 文件的读写 11.3.2 单行读写文件 fgets()函数用于读取一行字符串,或读取指定长度的字符串,其语法格式如下: 在上述语法格式中,fgets()函数会将fp所指向文件中的字符串读入到ch所指向的内存,从fp指向的文件读取一个长度为n-1的字符串,然后在最后加一个“\0”存放到字符数组ch中。若在读完n-1个字符之前遇到“\n”或文件结束符EOF,输入结束。 char * fgets(char* ch,int n,FILE* fp);

11.3 文件的读写 11.3.2 单行读写文件 fputs()函数将指定的字符串写入到文件中,其语法格式如下: 在上述语法格式中,fputs()函数中第一个参数ch表示要写入文件的字符串指针,第二个参数fp表示文件指针。将指针ch所指向的字符串写入到fp所指向的文件中,直到碰到‘\0’字符结束,但是‘\0’不会写入文件。如果发生错误,fputs()函数会返回EOF,如果正常,就返回正整数。 接下来通过一个简单案例来学习一下fgets()和fputs()函数的使用,在学习这个案例之前必须要在根目录中创建一个read.txt文件,如例11-5所示。 int fputs(const char *ch, FILE* fp);

11.3 文件的读写 11.3.2 单行读写文件 例11-5 1 #include <stdio.h> 2 void main() 3 { 4 FILE *fin, *fout; 5 char buf[1024]; //读写文件数据缓冲区 6 if ((fin = fopen("read.txt", "r")) == NULL) //打开源文件 7 { 8 printf("打开文件read.txt出错!\n"); 9 } 10 if ((fout = fopen("write.txt", "w")) == NULL) //打开目的文件 11 { 12 printf("打开文件write.txt出错!\n"); 13 } 14 fgets(buf,1024, fin); 15 printf("读文件数据完毕!\n"); 16 fputs(buf, fout); 17 printf("写文件数据完毕!\n"); 18 fclose(fin); 19 fclose(fout); 20 }

11.3 文件的读写 11.3.2 单行读写文件 运行结果如图11-12所示。 图11-12 运行结果 从图11-12中可以看出,文件读取操作成功了。程序第4行定义两个文件指针变量fin和fout变量,第6行和第10行分别使用fopen()函数打开文件,第14、16行使用fgets()和fputs()函数分别向文件中读取和写入数据。最后程序18、19行分别关闭两个文件指针。

11.3 文件的读写 11.3.2 单行读写文件 为了验证上述程序是按行读取的,接下来打开操作的文件进行对比,如图11-13所示。 图11-13 read.txt和write.txt 从图11-13可以看出,文件read.txt中有两行字符,而write文件中只有一行字符,因此可以说明此文件的操作是单行的读写操作。

11.3 文件的读写 11.3.2 单行读写文件 多学一招:格式化读写 通过前面的讲解可以知道printf()函数和scanf()函数都是以终端作为对象的格式化输入输出函数,其实也可以对文件进行格式化输入输出,这时就要用到fprintf()函数和fscanf()函数,从函数名可以看出,它们只是在printf()函数和scanf()函数前面加了“f”,表示以文件为对象的。它们与printf()函数和scanf()函数类似,都是格式化读写函数,只是有一点不同,fprintf()函数和fscanf()函数的读写对象不是终端而是磁盘文件,它们的调用方式如下: fprintf(文件指针,格式化字符串,输出列表); fscanf(文件指针,格式化字符串,输入列表);

11.3 文件的读写 11.3.2 单行读写文件 多学一招:格式化读写 例如,下面的代码就是使用fprintf()函数输出字符串“Hello, world”: 例如:下面的代码就是从文件流fp中读入一个整数,并存在变量d中: 磁盘文件上如果有一个整数3,则将该整数读入到内存并传递给变量d。 fprintf(fp, "%s", "Hello, world"); fscanf(fp, "%d", &d);

11.3 文件的读写 11.3.3 二进制读写文件 在前面的两个小节中,讲解了文本文件的读写操作,在计算机中文件实际上都是以二进制的形式存在于硬盘上,然而二进制数据不能作为字符来进行读写。所以C语言提供了fread()函数和fwrite()函数,这两个函数可以直接以二进制的形式来操作文件。接下来将对fread()和fwrite()函数进行详细讲解。

11.3 文件的读写 11.3.3 二进制读写文件 fread()函数的语法格式如下: 上述代码中,参数buffer表示要读取的数组地址,参数size表示每个数据项的字节数,count表示要读取的数据项个数,fp表示文件指针。 size_t fread(void *buffer, size_t size, size_t count, FILE *fp);

11.3 文件的读写 11.3.3 二进制读写文件 fwrite()函数的语法格式如下: fwrite()函数中的参数与fread()函数中的相同,这里就不再做解释。通过上面的讲解,读者对fread()和fwrite()函数有了一定的了解,接下来通过一个案例来练习如何使用这两个函数来进行二进制的读写,如例11-6所示。 size_t fwrite(const void* buffer, size_t size, size_t count, FILE* fp);

11.3 文件的读写 11.3.3 二进制读写文件 例11-6 1 #include <stdio.h> 2 void main(void) 3 { 4 FILE* fp; //定义一个文件指针 5 char list[30]; //定义一个字符数组 6 int i, numread, numwritten; 7 //以只写方式打开一个文件,如果文件不存在则创建 8 if ((fp = fopen("fread.txt", "w+")) != NULL) 9 { 10 //将26个字符循环写入字符数组 11 for (i = 0; i < 10; i++) 12 { 13 list[i] = (char)('z' - i); 14 } 15 numwritten = fwrite(list, sizeof(char), 10, fp); //将字符数组内容写入到文件中 16 printf("写入的字符数为:%d\n", numwritten); //打印写入字符数 17 fclose(fp); //关闭当前文件 18 }

11.3 文件的读写 11.3.3 二进制读写文件 19 else 20 { 21 printf("文件打开失败\n"); 22 } 20 { 21 printf("文件打开失败\n"); 22 } 23 if ((fp = fopen("fread.txt", "r+")) != NULL) //以只读方式打开一个文件 24 { 25 numread = fread(list, sizeof(char), 10, fp); //将文件中的字符读取到list数组中 26 printf("读取的字符数为:%d\n", numread); 27 printf("输出读取的字符串为:%.10s\n", list); //输出list数组中的内容 28 fclose(fp); //关闭当前文件 29 } 30 else 31 { 32 printf("文件打开失败\n"); 33 } 34 }

11.3 文件的读写 11.3.3 二进制读写文件 运行结果如图11-14所示。 图11-14 运行结果 从图11-14中可以看出,文件读写操作成功,并将写入到文件中的字符输出至控制台。其中,程序第15行使用fwrite()函数将list字符数组中的数据写入到文件中并返回写入的字符个数,第25行中使用fread()函数将文件中的内容读取到字符数组中,并输出字符数组的内容。

11.3 文件的读写 11.3.3 二进制读写文件 需要注意的是,二进制模式是将内存中的数据直接传送到文件中,在文本模式下具有特殊意义的字符,如‘\n’和‘\0’,在二进制模式下就没有意义了。

11.4 文件的随机读写 11.4.1 文件位置指针的定位 随机读写文件与顺序读写文件不同,顺序读写文件只能从头开始,并且按顺序读取数据的。而随机读写文件是将文件位置指针指向需要读写的位置,然后再进行读写,也就是说文件位置指针是随机读写文件的关键。接下来针对文件位置指针的三个相关函数进行简单的介绍,具体如下:

11.4 文件的随机读写 11.4.1 文件位置指针的定位 1、rewind()函数 上述语法格式中,void表示该函数无返回值,参数fp表示一个文件指针。 void rewind(FILE * fp);

11.4 文件的随机读写 11.4.1 文件位置指针的定位 2、fseek()函数 上述语法格式中,int表示函数的返回值类型,参数fp表示一个文件指针,参数offset表示根据参数origin 来移动读写位置的偏移量,参数origin用来决定文件位置指针的起始位置。其中,参数origin的值有三个,具体如下: int fseek(FILE * fp, long offset, int origin);

11.4 文件的随机读写 11.4.1 文件位置指针的定位 SEEK_SET:对应的数字值为0,表示从文件开头进行偏移; SEEK_CUR:对应的数字值为1,相对于文件位置指针当前位置进行偏移; SEEK_END:对应的数字值为2,相对于文件末尾进行偏移。 需要注意的是,fseek()函数调用成功会返回0,但如果有错误则返回-1;该函数一般用于二进制文件,因为文本文件要进行字符转换,计算位置时往往会发生混乱。

11.4 文件的随机读写 11.4.1 文件位置指针的定位 3、ftell()函数 上述语法格式中,long为函数的返回值类型,参数fp表示文件指针。 需要注意的是,ftell()函数调用成功后,返回文件位置指针的当前位置,但如果当文件不存在或发生其他错误时,则函数的返回值为-1L。 long ftell(FILE * fp);

11.4 文件的随机读写 11.4.1 文件位置指针的定位 至此,文件位置指针的相关函数就介绍完了。为了让读者更好地掌握这三个函数,接下来通过一个案例来演示一下它们的使用方法,如例11-7所示。

11.4 文件的随机读写 11.4.1 文件位置指针的定位 例11-7 1 #include <stdio.h> 2 void main() 3 { 4 FILE * fp; 5 long offset; 6 fp = fopen("D:\\itcast\\chapter09\\test.txt", "r"); //只读方式打开文件,文件必须存在 7 fseek(fp, 5, SEEK_SET); //将文件位置指针从头开始偏移5位 8 printf("offset = %d\n", ftell(fp)); //打印文件位置指针的当前位置 9 rewind(fp); //将文件位置指针指向文件开头 10 printf("offset = %d\n", ftell(fp)); 11 fseek(fp, 10, SEEK_CUR); //将文件位置指针从当前位置开始偏移10位 12 printf("offset = %d\n", ftell(fp)); 13 fclose(fp); 14 }

11.4 文件的随机读写 11.4.1 文件位置指针的定位 运行结果如图11-15所示。 图11-15 运行结果 从图11-15中可以看出,控制台成功打印出了文件位置指针的位置。程序中第7行和第11行使用fseek()函数实现了文件位置指针的移动,第9行中使用rewind()函数将文件位置指针移动到文件开头,并通过printf()函数格式化输出每次的文件位置指针的偏移量。

11.4 文件的随机读写 11.4.2 对文件进行随机读写 通过上一小节的讲解,大家对文件位置指针的相关函数有了一定的了解,接下来以fseek()函数的使用为例,来演示如何对文件进行随机读写,具体代码如例11-8所示。

11.4 文件的随机读写 11.4.2 对文件进行随机读写 例11-8 1 #include <stdio.h> 2 #include <string.h> 3 void main() 4 { 5 FILE *fin; 6 char buf[128]; 7 memset(buf, '\0', 128); //初始化内存的缓冲区内容。 8 char filepathIn[255]; 9 printf("请输入要操作的文件路径:"); 10 scanf("%s", filepathIn); 11 if ((fin = fopen(filepathIn, "r")) == NULL) //打开源文件 12 { 13 printf("打开文件出错!\n"); 14 } 15 fseek(fin, 5, SEEK_SET); //文件操作指针偏移量为5个字节 16 fread(buf, sizeof(unsigned char), 10, fin); 17 printf("读取的数据内容是:%s \n", buf); 18 fclose(fin); 19 }

11.4 文件的随机读写 11.4.2 对文件进行随机读写 程序运行后,输入“D:\itcast\chapter09\test.txt”文件的路径后,结果如图11-16所示。 图11-16 运行结果 从图11-16中可以看出,控制台输出的内容是“fghijklmno”。在程序中第15行和16行代码实现了读取文件中第5个字符后的10个字符的功能。接下来打开“test.txt”文件来验证读取的内容是否正确,文件内容如图11-17所示。

11.4 文件的随机读写 11.4.2 对文件进行随机读写 图11-17 运行结果 从图11-17中可以看出,文件中第5个字符后的10个字符是“fghijklmno”,这与程序输出结果一致,说明随机读取文件中内容成功了。

本章首先讲解了文件的基本概念,然后讲解了文件的基本操作,包括文件的打开与关闭及文件的读写,最后讲解了文件的随机读写。通过本章的学习,读者可以对文件进行读写操作,从而站在更高的层面来理解和使用文件。