文件操作浅论(巨无敌详细讲解)

2024-03-12 14:10

本文主要是介绍文件操作浅论(巨无敌详细讲解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文件操作在初级C语言中是一个概念多且繁琐的章节。本篇文章采用先总后分的写法,适合于学C语言的程序猿阅读,相信这里面的内容在你看过的文件操作专题都大体出现过。觉得这篇文章总结的较为详细的话别忘了收藏与关注哦(鄙人觉得扩展的还挺全面的),我是一枚小比特,希望在接下来的沉潜岁月里陪你一起努力勇攀高峰!

目录

文件类型、文件名。文件系统

主要函数总结

 主要文件打开方式

fopen()与flcose()

fgetc()与fputc()

fgets()与fputs()

fread()与fwrite()

关于被错误使用的feof()

尾声


文件类型、文件名。文件系统

C语言文件有两种类型:二进制文件(demo.bin)和文本文件(demo.txt)。

文件名包括三部分:文件路径+文件名主干+文件后缀   e.g:D:\shilv\test.txt

C语言文件系统也有两种类型:缓冲型(利用文件指针标识文件)非缓冲型(没有文件指针,使用称为文件号的整数来标识文件)。本文章主要介绍的是缓冲型文件系统

缓冲型文件系统中,关键性概念是“文件类型指针”,简称“文件指针”。

文件指针pf(有些教材上是fp,和本文章的pf的唯一区别是字母不同而已)是指向FILE结构类型的指针变量,其定义为

FILE* pf

主要函数总结

函数函数原型大致用法
fopen()FILE *fopen( const char *filename, const char *mode )
FILE* pf = fopen("test.txt", "r");

fclose()int fclose( FILE *stream )
fclose(pf);

fgetc()

int fgetc( FILE *stream )

fgetc(pf);

fputc()int fputc( int c, FILE *stream )
fputc('b', pf);

fgets()char *fgets( char *string, int n, FILE *stream )
fgets(buf, 1024, pf);

fputs()int fputs( const char *string, FILE *stream )
fputs("hello", pf);

feof()

int feof( FILE *stream )

while(!feof(pf));

fscanf()

int fscanf( FILE *stream, const char *format [, argument ]... )

fscanf(stdin, "%d %f %s", &(s.n), &(s.score), s.arr);

fprintf()

int fprintf( FILE *stream, const char *format [, argument ]...)

fprintf(stdout, "%d %f %s", s.n, s.score, s.arr);

fread()

size_t fread( void *buffer, size_t size, size_t count, FILE *stream )

fread(&tmp, sizeof(struct S), 1, pf);

fwrite()size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream )
fwrite(stu,sizeof(STUDENT),n,fp);

strerror()char *strerror( int errnum )
printf("%s\n", strerror(errno));

perror()

void perror( const char *string )

perror("open file test2.txt");

sscanf()int sscanf( const char *buffer, const char *format [, argument ] ... )
sprintf()int sprintf( char *buffer, const char *format [, argument] ... )
fseek()

int fseek( FILE *stream, long offset, int origin )

fseek(pf, 5, SEEK_SET);

ftell()

long ftell( FILE *stream )

int pos = ftell(pf);

rewind()void rewind( FILE *stream )
rewind( stream );
fflush()

int fflush( FILE *stream )   

fflush(stdin);

如上只是对函数作出整理方便读者了解个大概,具体函数功能如何下面将会一一讲解。

 主要文件打开方式

文件使用方式含义如果指定文件不存在
“r”(只读)为了输入数据,打开一个已经存在的文本文件出错
“w”(只写)为了输出数据,打开一个文本文件(会把文本里原来的内容清空哦)建立一个新的文件
a”(追加)向文本文件尾添加数据建立一个新的文件
“rb”(只读)为了输入数据,打开一个二进制文件出错
“wb”(只写)为了输出数据,打开一个二进制文件建立一个新的文件
“ab”(追加)向一个二进制文件尾添加数据出错
“r+”(读写)为了读和写,打开一个文本文件出错
“w+”(读写)为了读和写,建议一个新的文件建立一个新的文件
“a+”(读写)打开一个文件,在文件尾进行读写建立一个新的文件
“rb+”(读写)为了读和写打开一个二进制文件出错
“wb+”(读写)为了读和写,新建一个新的二进制文件建立一个新的文件
“ab+”(读写)打开一个二进制文件,在文件尾进行读和写建立一个新的文件

不用记,把"r" "w" "a"这三个理解透彻就能融会贯通啦,多说一嘴,有"b"的话就是打开二进制文件。

  

fopen()与flcose()

ANSIC 规定使用fopen函数来打开文件,fclose函数来关闭文件。

FILE *fopen( const char *filename, const char *mode )

fopen()有两个参数,第一个参数filename代表文件名,第二个形参mode表示文件打开方式。

int fclose( FILE *stream )

函数fclose()返回一个整形数值,当文件关闭成功时,返回0值,否则返回一个非0值。参考代码如下:

#include <stdio.h>
int main()
{FILE* pf = fopen("test2.txt", "r");if (pf == NULL){return 0;        //又出现了判断文件打开成功与否}fclose(pf);pf = NULL;return 0;
}

如上所示,为什么要判断文件打开成功与否呢?跟上篇动态内存分配类似,是因为文件并不是每次都能呗成功地打开的。例如,当文件不存在或者已经损坏时,文件打开就会失败。这是一个至关重要的点!

fgetc()与fputc()

int fgetc( FILE *stream )

fgetc()用于从一个只读或读写方式打开的文件上读字符,该函数较为简单,用法如下:

#include <stdio.h>
int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){return 0;}int ch = fgetc(pf);printf("%c", ch);ch = fgetc(pf);printf("%c", ch);ch = fgetc(pf);printf("%c", ch);fclose(pf);pf = NULL;return 0;
}

实现前:在文本输入x个字符

实现后:文本上的字符就会呗读取到控制台上 

 

int fputc( int c, FILE *stream

fputs()用于将一个字符写到一个文件上。用法如下:

#include <stdio.h>
int main()
{FILE* pf = fopen("test.txt", "w");if (pfWrite == NULL){return 0;}fputc('b', pf);fputc('i', pf);fputc('t', pf);fclose(pf);pf = NULL;return 0;
}

实现前:

实现后:

fgetc()和fputc()还能同时使用

#include <stdio.h>
int main()
{int ch = fgetc(stdin);fputc(ch, stdout);return 0;                   //你输入什么它就输出什么
}

fgets()与fputs()

char *fgets( char *string, int n, FILE *stream )

fgets()作用是从文件中读取字符串,它的三个参数可以这样理解:第一个参数是dest(目的地),第二个是读取字符的个数,第三个是src(源头)。大致用法如下:

#include <stdio.h>
int main()
{char arr[1024] = { 0 };FILE* pf = fopen("test.txt", "r");if (pf == NULL){return 0;}fgets(arr, 1024, pf);puts(arr);                 //相当于printf("%s", arr);fgets(arr, 1024, pf); puts(arr);fclose(pf);pf = NULL;return 0;
}

操作过程大致如fgetc(),留给读者自行操作检验。

int fputs( const char *string, FILE *stream )

fputs()函数第一个参数想是要输入的字符串,第二个参数是目标文本。大致用法如下:

#include <stdio.h>
int main()
{char buf[1024] = { 0 };FILE* pf = fopen("test.txt", "w");if (pf == NULL){return 0;}fputs("hello", pf);fputs("zjr", pf);return 0;
}

操作过程大致如fputc(),留给读者自行操作检验。

fread()与fwrite()

这两个函数是用于一次读取一组数据,即按数据块读写文件的。

size_t fread( void *buffer, size_t size, size_t count, FILE *stream )

fread()函数第一个参数是待读入数据块的起始地址,第二个参数是size是每个数据块的大小,第三个参数是最多允许读取的数据块的个数,函数返回的是实际读到的数据块个数

size_t int fwrite( const void *buffer, size_t size, size_t count, FILE *stream )

fwrite()函数第一个参数是待输出数据块的起始地址,第二个参数是size是每个数据块的大小,第三个参数是最多允许写入的数据块的个数,函数返回的是实际写入的数据块个数

fseek()与ftell()

这两个函数能实现文件的随机读写,理解难度不大。

int fseek( FILE *stream, long offset, int origin )         offset是长整型位移量

long ftell( FILE *stream )

查询MSDN可知fseek()有三种用法:

SEEK_CUR->光标定位到当前位置

SEEK_END->光标定位到字符串末尾

SEEK_SET->光标定位到字符串开头   (关于光标是什么我将在不久的将来为大家讲解)

话不多说,上代码:

#include <stdio.h>
int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){return 0;}fgetc(pf);int pos = ftell(pf);printf("%d\n", pos);fseek(pf, 5, SEEK_SET);      pos = ftell(pf);printf("%d\n", pos);fclose(pf);pf = NULL;return 0;
}

看到这的小伙伴建议自己去操作体会一下,真的一操作就清晰明了啦。

关于被错误使用的feof()

在文件读取过程中,不能用feof()函数的返回值直接用来判断文件的是否结束,而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束

1.文本文件读取是否结束,判断返回值是否为EOF(fgetc),或者NULL(fgets)。

e.g: ·fgetc()判断是否为EOF;

·fgets()判断返回值是否为NULL;

2.二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。

e.g:fread()判断返回值是否小于实际要读的个数。

尾声

感谢能阅读到者的你,以上就是我对文件操作的浅论,有些未解释到的函数由于鄙人现阶段能力不足无法作出对应讲解,未来将会发布文件操作进阶版。希望我的这篇文章能够帮助到将要学文件操作或者正在学的文件操作的你。如果你觉得这篇文章对你理解文件操作有帮助的话,请留下你的收藏与点赞哦。

 

这篇关于文件操作浅论(巨无敌详细讲解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/qq_64263760/article/details/121902229
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/801514

相关文章

Nginx中配置HTTP/2协议的详细指南

《Nginx中配置HTTP/2协议的详细指南》HTTP/2是HTTP协议的下一代版本,旨在提高性能、减少延迟并优化现代网络环境中的通信效率,本文将为大家介绍Nginx配置HTTP/2协议想详细步骤,需... 目录一、HTTP/2 协议概述1.HTTP/22. HTTP/2 的核心特性3. HTTP/2 的优

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.

Oracle数据库常见字段类型大全以及超详细解析

《Oracle数据库常见字段类型大全以及超详细解析》在Oracle数据库中查询特定表的字段个数通常需要使用SQL语句来完成,:本文主要介绍Oracle数据库常见字段类型大全以及超详细解析,文中通过... 目录前言一、字符类型(Character)1、CHAR:定长字符数据类型2、VARCHAR2:变长字符数

Win11安装PostgreSQL数据库的两种方式详细步骤

《Win11安装PostgreSQL数据库的两种方式详细步骤》PostgreSQL是备受业界青睐的关系型数据库,尤其是在地理空间和移动领域,:本文主要介绍Win11安装PostgreSQL数据库的... 目录一、exe文件安装 (推荐)下载安装包1. 选择操作系统2. 跳转到EDB(PostgreSQL 的

Python3.6连接MySQL的详细步骤

《Python3.6连接MySQL的详细步骤》在现代Web开发和数据处理中,Python与数据库的交互是必不可少的一部分,MySQL作为最流行的开源关系型数据库管理系统之一,与Python的结合可以实... 目录环境准备安装python 3.6安装mysql安装pymysql库连接到MySQL建立连接执行S

将Mybatis升级为Mybatis-Plus的详细过程

《将Mybatis升级为Mybatis-Plus的详细过程》本文详细介绍了在若依管理系统(v3.8.8)中将MyBatis升级为MyBatis-Plus的过程,旨在提升开发效率,通过本文,开发者可实现... 目录说明流程增加依赖修改配置文件注释掉MyBATisConfig里面的Bean代码生成使用IDEA生

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子