理解C语言——从小菜到大神的晋级之路(11)——文件输入输出

2023-11-23 04:38

本文主要是介绍理解C语言——从小菜到大神的晋级之路(11)——文件输入输出,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        本节视频地址:点击这里

        在我们先前的程序中,所处理的数据或者在代码中预先指定,或者通过命令行窗口手动输入。事实上这两种方法都是效率不高的方法,相对更常用的是通过文件读写操作处理以文件形式保存的数据。C语言中的文件操作主要包括文件数据的读、写和定位等辅助操作。



1、文件



        C语言中定义了FILE这一结构用于文件操作,这一结构定义了表示文件的数据流以及用于控制文件操作的信息,如指向文件某个位置的标识、指向缓存区的指针和表示文件的状态信息等。在我们自己的源代码中定义一个FILE类型的实体通常没有意义。通常,实际操作FILE类型的实例仅在C语言提供的库函数内部完成,在编程过程中只需要定义一个FILE类型的指针变量,并对这个指针变量进行各种操作。例如我们需要输入输出两个文件,那么可以定义两个空的文件指针供后面使用:
FILE *pFin = NULL, *pFout = NULL;


2、打开文件



        对一个文件进行操作,必不可少的两个因素就是文件的完整路径和操作方式,而对文件进行操作使用的是指向文件的指针,那么一个极为关键的问题就是如何将路径和操作方式同文件指针联系起来。在C语言中,实现这一方法的途径是通过打开文件函数。打开文件函数的原型为:
FILE * fopen ( const char * filename, const char * mode );

        该函数的第一个参数传入的是目标文件的路径,第二个参数用于表示文件的操作模式,可以代表读/写、文本/二进制、刷新/续写等不同的模式。各种模式的含义有:

“r”

读文本

“rb”

读二进制

“r+”

更新读文本

“rb+”

更新读二进制

“w”

写文本

“wb”

写二进制

“w+”

更新写文本

“wb+”

更新写二进制

“a”

续写文本

“ab”

续写二进制

“a+”

更新续写文本

“ab+”

更新续二进制


        使用fopen函数打开一个文件并进行操作完成后,需要将这个文件进行关闭。关闭文件使用fclose函数完成。fclose函数原型为:

int fclose ( FILE * stream );

        该函数只有一个参数,即打开文件的指针。

        将一个文件打开、处理、最后关闭的例子如下:
int main()
{FILE *pF = NULL;fopen(“file.bin”, “rb");//文件处理fclose(pF);pF = NULL;
}


3、文本文件读写



        文件数据的读写通常有两种常用的方式,其中一种是按照文本文件的方式读写文件中的ASCII码信息,另一种方式是按照二进制文件的方式读取文件本身所表示的比特流。如果希望进行文本文件的读写操作,则在打开文件时就需要指定文件按照文本方式读取或写入。C语言为文本方式读写数据定义了多种输入输出函数:

(1)getc和putc函数


        getc和putc函数是最简单的文本读写函数,分别实现一个字符常量或变量的读取和写入操作。两个函数的声明分别如下:
int getc ( FILE * stream );
int putc ( int character, FILE * stream );

        getc函数只有一个参数就是读取目标文件的指针;putc函数第一个参数表示将要被写入目标文件的文本字符的ASCII码,第二个参数表示目标文件的指针。在putc中,字符使用int表示,但是在向文件写入的过程中,这个参数会被转化为unsigned char型进行写入。当读取文本文件到结束时,getc函数将会返回一个EOF字符,该字符的ASCII值为-1这一非法值,表示文件已结束。


(2)fgets和fputs函数


        这两个函数用于从文本文件中读取和写入字符串。声明分别如下:
char * fgets ( char * str, int num, FILE * stream );
int fputs ( const char * str, FILE * stream );

        fgets函数调用时需要三个参数,第一个参数指向字符串的首地址,第二个参数表示读入字符串的最大长度,第三个参数表示打开文件的指针。需注意,当指定第二个参数num时,这个参数所表示的长度包括了字符串结尾的0,因此可以读入的最多的字符个数为num-1。如果在读出num-1个字符之前就遇到换行符或EOF,则在这里结束读入,并在末尾补上\0。当读取成功时,函数将字符串的缓存str作为返回值返回;如果读取失败,函数将返回一个空指针。

        fputs函数用于将字符串输出到文本文件中,第一个参数表示指向字符串常量或变量的指针,第二个参数表示写入文件的指针。需注意的是,该函数写入字符串不会输出结尾的0或者换行符,如果连续调用fputs将会使多个字符串首尾相接无法分辨。因此使用时应注意手动添加'\n'等间隔符以示区分。

(3)fscanf和fprintf函数


        同scanf和printf函数类似,fscanf和fprintf函数表示格式化输入和输出数据,只是输入输出的对象由控制台界面变为文本文件。两个函数的声明如下:
int fscanf ( FILE * stream, const char * format, ... );
int fprintf ( FILE * stream, const char * format, ... );

        事实上,将两个函数的第一个参数,即指向打开文件的指针分别换成stdin和stdout,则他们的功能同scanf和printf将完全一样。因为stdin和stdout分别表示的就是代表终端键盘和终端屏幕的文件指针。
两个函数的调用方法同scanf与printf类似。


4、二进制文件读写



        对于二进制形式的文件而言无所谓格式的概念,只有按照文件原始的0/1存储方式保存着一种方法。因此读取二进制文件也不存在文本文件中各种格式、换行等因素,只有读取/写入数据和判断文件末尾两种基本情况。C语言中定义二进制文件的读写函数分别为fread和fwrite,声明方式如下:
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

        fread函数定义了4个参数,第一个参数ptr为指向接受读取进来的文件数据的缓存的指针,这部分缓存必须是预先成功分配好的足够大的内存空间,如果不是合法的可写入的内存或者空间不足,在读取时程序将出现崩溃;第二个参数size表示 每一个数据单元所占字节数,这个字节通常用于表示二进制文件中数据按多少字节作为一个单元;第三个参数count表示总共读取多少个数据单元,第二三个参数的乘积size × count就是从二进制文件中读取的总的字节数;第四个参数表示打开的二进制文件指针。函数的返回值为实际读取到缓存区中数据的长度。

        fwrite函数的定义和使用方式同fread类似,只是作用是以二进制的方式向文件中写入数据。

        需要注意的是,以二进制方式读取文件时,读取的数据同文本读取时获得的ASCII码不同。二进制读取的数据的范围可以非常广,不局限于0~255之间,因此用-1代表文件结束的EOF便不再适用。在二进制文件读写中判断文件结束应使用feof函数。当函数feof(pF)返回值为1时,表示文件已经遇到文件结束,否则该函数会返回0。


5、文件定位函数



        在前面的文件读写函数中,无论读取的数据或长或短,下一次读写仍能够继续上一次结束的位置继续操作。这是由于文件结构中有“文件位置指针”这一功能。当使用fopen打开文件是,文件位置指针便指向了文件开头。每次进行读写操作,程序都会对文件位置指针处的数据进行读写。操作完成后,文件位置指针会根据读写的数据长度移动到新的位置等待下一次操作。这一切都是系统自动完成,不需要程序员进行任何干预。

        然而有时候,我们希望人为地对文件位置指针进行修改。为了实现这样的功能,C语言提供了文件定位函数,主要有fseek、ftell和rewind等。

(1)fseek函数


        fseek函数用于将文件位置指针移动到指定的位置,该函数的声明为:
int fseek ( FILE * stream, long int offset, int origin );

        该函数的第一个参数表示打开文件的指针,第二个参数表示相对于origin的偏移量(在文本文件中,该值或为0或为ftell返回的一个值),第三个参数表示文件位置指针的参考位置。不同的origin的设置代表文件相对不同位置的偏移:

Origin取值

SEEK_SET

SEEK_CUR

SEEK_END

参考位置

文件头

当前位置

文件末尾


        当文件指针pF指向一个二进制文件,则调用下面的语句使文件位置指针移动到距离文件头30字节的位置:

fseek(pF, 30L, SEEK_SET);

        调用下面的语句使文件指针移动到距离文件末尾15个int型数据长度的位置:

fseek(pF, 15L * sizeof(int), SEEK_END);

        如果文件指针指向一个文本文件,下面的语句使文件位置指针移动到文件的开头和结尾:

fseek(pF, 0L, SEEK_SET);
fseek(pF, 0L, SEEK_END);

(2)ftell函数


        该函数用于获取当前指针距离文件开头的距离,声明如下:
long int ftell ( FILE * stream );

该函数只有一个参数就是文件的指针。它的返回值代表了当前位置距离文件开始有多少个字节。


(3)rewind函数


        该函数的作用在于将文件位置指针重置与文件开头,声明如下:
void rewind ( FILE * stream );

        该函数只有一个参数即文件指针,没有返回值。它的作用同下面fseek的用法类似:

fseek(pF, 0L, SEEK_SET);


这篇关于理解C语言——从小菜到大神的晋级之路(11)——文件输入输出的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/415398

相关文章

C语言中%zu的用法解读

《C语言中%zu的用法解读》size_t是无符号整数类型,用于表示对象大小或内存操作结果,%zu是C99标准中专为size_t设计的printf占位符,避免因类型不匹配导致错误,使用%u或%d可能引发... 目录size_t 类型与 %zu 占位符%zu 的用途替代占位符的风险兼容性说明其他相关占位符验证示

C语言进阶(预处理命令详解)

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块... 目录1.宏定义1.1不带参宏1.2带参宏2.头文件的包含2.1头文件中的内容2.2工程结构3.条件编

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

Java Spring的依赖注入理解及@Autowired用法示例详解

《JavaSpring的依赖注入理解及@Autowired用法示例详解》文章介绍了Spring依赖注入(DI)的概念、三种实现方式(构造器、Setter、字段注入),区分了@Autowired(注入... 目录一、什么是依赖注入(DI)?1. 定义2. 举个例子二、依赖注入的几种方式1. 构造器注入(Con

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

Go语言中make和new的区别及说明

《Go语言中make和new的区别及说明》:本文主要介绍Go语言中make和new的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 概述2 new 函数2.1 功能2.2 语法2.3 初始化案例3 make 函数3.1 功能3.2 语法3.3 初始化

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁