C/C++文件读写(最全方法,多种实现)

这篇具有很好参考价值的文章主要介绍了C/C++文件读写(最全方法,多种实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C/C++实战入门到精通 https://blog.csdn.net/weixin_50964512/article/details/125710864

前言

本章主要详解C/C++对文件的所有常见方法汇总

先要明白一个概念,即几乎在所有编程语言中,文件处理都是一个非常重要的模块

因为文件可以实现对数据大量且长久的存储

一、文件处理过程

无论什么编程语言,处理文件的过程都可以分为以下三步:

  1. 打开文件
  2. 操作文件
  3. 关闭文件

所以当我们操作文件的时候,请务必牢记这三点,因为该逻辑几乎是所有语言通用的,只不过具体实现细节略有差异

二、C处理文件

首先来看C中处理文件的方式,因为C是面向过程的语言,所以使用起来较为繁琐,你需要记住很多函数

而这些函数所在的头文件为:

#include<cstdio> //或者#include<stdio.h>均可

同时需要注意的是:

C语言库中的函数,很多都存在安全隐患,就会存在一个相应的安全函数,一般对应的安全函数名称都是在原函数后添加_s后缀

例如:fopen的安全函数为fopen_s

相比较而言,安全函数会比标准函数使用更繁琐,所以很多情况下我们会习惯于使用标准函数,

但在VS环境下直接使用不安全的函数,会直接报错,编译无法通过,此时就必须要定义对应的宏才能正常使用

而安全函数则无需定义任何宏,可直接使用

具体使用哪一种看个人习惯,官方推荐使用安全函数

1.打开文件

首先是打开文件的函数:

//标准函数:
FILE* fopen(
const char * _FileName,//要打开的文件名,不指定路径,则在当前文件夹找
const char * _Mode //打开的模式 读r 写w 或追加a
);
//返回值:打开失败返回NULL,打开成功则返回指向文件的标识符

//安全函数
 errno_t fopen_s(
FILE**      _Stream, //保存打开文件后的标识符
const char * _FileName, //要打开的文件名,不指定路径,则在当前文件夹找
const char * _Mode //打开的模式 读r 写w 或追加a
            );
 //返回值:打开成功返回0,打开失败则返回对应错误代码

两种函数的使用区别:

#define _CRT_SECURE_NO_WARNINGS //vs环境下,必须定义该宏,否则报错
#include<cstdio>
using namespace std;
int main() {
	FILE* file = fopen("1.txt","r"); //以读的方式打开文件
	if (file == NULL) { //file为NULL,则打开文件失败,退出程序
		return -1;
	}
}
#include<cstdio>
using namespace std;
int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","r"); //以读的方式打开文件
	if (err != 0) { //err不为0,则打开文件失败,退出程序
		return -1;
	}
}

对于mode参数,有如下选择:
C/C++文件读写(最全方法,多种实现)

2.读文件

然后就是文件操作中的读:

//标准函数:
size_t  fread(
void*  _Buffer, //读取到的内容存放空间
size_t _ElementSize, //每次读多少个字节
size_t _ElementCount, //读多少次
FILE*  _Stream //文件标识符
);
//返回值:实际读取的次数,注意,实际的取得字节数应该是该返回值和_ElementSize参数相乘,所以一般_ElementSize参数填1

//安全函数:
size_t fread_s(
void*  _Buffer,//读取到的内容存放空间
size_t _BufferSize, //第一个参数指示的缓存区大小
size_t _ElementSize,//每次读多少个字节
size_t _ElementCount,//读多少次
FILE*  _Stream //文件标识符
);
//返回值:实际读取的次数,注意,实际的取得字节数应该是该返回值和_ElementSize参数相乘,所以一般_ElementSize参数填1

两者使用区别:

#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
using namespace std;
int main() {
	FILE* file = fopen("1.txt","r"); //以读的方式打开文件
	if (file == NULL) { //file为NULL,则打开文件失败,退出程序
		return -1;
	}
	char buf[0xFF]; //定义存放读取内容的缓存区
	size_t size=fread(buf,1,100, file); //每次读一个字节,读100次
}
#include<cstdio>
using namespace std;
int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","r"); //以读的方式打开文件
	if (err != 0) { //err不为0,则打开文件失败,退出程序
		return -1;
	}
	char buf[0xFF];  //定义存放读取内容的缓存区
	size_t size=fread_s(buf,sizeof(buf),1,100,file);//每次读一个字节,读100次
}

除了上面最基本的读文件数据函数,还有一些其它读操作的函数:

  1. fgetc:从文件中读取一个字符
int fgetc(
FILE* _Stream //文件标识符
);
//返回值:返回读取到的一个字符
#define _CRT_SECURE_NO_WARNINGS //vs环境下必须定义该宏,否则报错
#include<cstdio>
using namespace std;
int main() {
	FILE* file = fopen("1.txt","r"); //已只读方式打开
	if (file == NULL) {  //打开失败直接返回
		return -1;
	}
	char c=fgetc(file); //读取一个字符
}
  1. fgets:从文件中读取一个字符串
char* __cdecl fgets(
char* _Buffer, //存放读到的字符缓冲区
 int   _MaxCount, //该缓存区的大小
FILE* _Stream //文件标识符
);
//返回值:成功为_Buffer指针,失败为NULL

使用:

#define _CRT_SECURE_NO_WARNINGS //vs环境下必须定义该宏,否则报错
#include<cstdio>
using namespace std;
int main() {
	FILE* file = fopen("1.txt","r"); //已只读方式打开
	if (file == NULL) {  //打开失败直接返回
		return -1;
	}
	char buf[0xFF];
	fgets(buf,0xFF,file); //读取一行字符串
}
  1. fscanf:按格式从文件中读取指定内容,与scanf函数类似
int fscanf(
 FILE*       const _Stream,//文件标识符
 char const* const _Format, //指定读取格式,与printf格式相同
        ... //存放读取内容的缓存区
)

使用:

#define _CRT_SECURE_NO_WARNINGS //vs环境下必须定义该宏,否则报错
#include<cstdio>
using namespace std;
int main() {
	FILE* file = fopen("1.txt","r"); //已只读方式打开
	if (file == NULL) {  //打开失败直接返回
		return -1;
	}
	int d; //存放数字
	char buf[0xFF]; //存放字符串的缓存区
	fscanf(file,"%d %s",&d,buf); //按格式读取文件内容
}
  1. fscanf_sfscanf的安全函数,作用相同
int fscanf_s(
 FILE*       const _Stream,//文件标识符
 char const* const _Format, //指定读取格式,与printf格式相同
        ... //存放读取内容的缓存区,注意在每个缓存区大小后一个参数为该缓存区的大小
)

使用:

#include<cstdio>
using namespace std;
int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","r");
	if (err != 0) {
		return -1;
	}
	int b;
	char buf[0xFF];
	fscanf_s(file,"%d %s",&b,buf,sizeof(buf));
	fclose(file);
}

4.写文件

文件操作主要就两个,上面说了读,下面就是写了:

标准函数:

size_t fwrite(
void const* _Buffer, //要写入的内容
size_t _ElementSize, //元素大小
size_t  _ElementCount, //元素个数
FILE*   _Stream //文件标识
 );

使用:

#define _CRT_SECURE_NO_WARNINGS //vs环境下必须定义该宏,否则报错
#include<cstdio>
using namespace std;
int main() {
	FILE* file = fopen("1.txt","w"); //已只读方式打开
	if (file == NULL) {  //打开失败直接返回
		return -1;
	}
	char buf[] = "test"; //要写入的内容
	fwrite(buf,1,sizeof(buf),file); //写入操作
}

该函数无安全函数

除了最基本的写入函数,还有一些其它的常用写操作函数:

  1. fputc:向文件中写入一个字符
int  fputc(
int   _Character,//要写入的字符
FILE* _Stream //文件标识符
);

使用:

#include<cstdio>
using namespace std;
int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","w");
	if (err != 0) {
		return -1;
	}
	int ret=fputc('c',file);//向file标识的文件写入一个c字符
}
  1. fputs:向文件中写入一个字符串
int fputs(
char const* _Buffer,//要写入的内容
FILE* _Stream //文件标识符
);

使用:

int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","w");
	if (err != 0) {
		return -1;
	}
	char buf[] = "test";
	int ret = fputs(buf,file); //将buf内的内容写入到file标识的文件
}

  1. fprintf:向文件中写入指定格式字符串,与pritnf函数类似
int fprintf(
 FILE* _Stream, //文件标识符
char const* const _Format, //写入格式 与printf使用方式相同
        ...
)

使用:

#include<cstdio>
using namespace std;
int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","w");
	if (err != 0) {
		return -1;
	}
	fprintf(file,"%d %s",4,"test");  //向fille标识的文件写入数字4和字符串test
}
  1. fprintf_sfprintf的安全函数

fprintf没什么区别,不再讲解

5.关闭文件

最后是关闭文件

int fclose(
FILE* _Stream //文件标识符
);

使用:

#include<cstdio>
using namespace std;
int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","w");
	if (err != 0) {
		return -1;
	}
	fclose(file);//关闭文件
}

三、C++处理文件

C++使用了面向对象对文件处理进行了封装,所以处理文件会比C方便很多

为了方便使用,C++封装了三个文件操作类

头文件:

#include<fstream> //处理文件的头文件
using namespace std; //引用该命名空间,不引用将必须使用std::fstring 的方式使用该类

代码:

首先是最通用的类fstream

#include<fstream>
using namespace std;
int main() {
	fstream file;
	file.open("1.txt",ios::out); //以只写模式打开文件
	char buf[] = "test";
	file.write(buf,sizeof(buf));//写入文件
	file.close(); //关闭文件

	file.open("1.txt", ios::app); //以追加模式打开文件
	char buf1[] = "test1";
	file.write(buf1, sizeof(buf));//写入文件末尾
	file.close(); //关闭文件

	file.open("1.txt",ios::in); //以只读方式打开文件
	char buf2[0xFF]; //存储读取的内容
	file.read(buf2,0xFF); //读文件
	file.close(); //关闭文件
}

模式选择:
C/C++文件读写(最全方法,多种实现)
但既然已经封装成为了类,那么在特定需求下,打开文件这个操作也是可以省略的

首先是读文件的类ifstream

#include<iostream>
#include<fstream>
using namespace std;
int main() {
	ifstream f("1.txt");
	char buf[0xFF];
	f.read(buf,0xFF); //普通读取
	char c=f.get(); //读取一个字符

	char bufLine[0xFF];
	f.getline(bufLine,0xFF); //读取一行
}

然后是写文件的类ofstream

#include<iostream>
#include<fstream>
using namespace std;
int main() {
	ofstream f("1.txt");
	char buf[0xFF];
	f.write("hello world",12); //普通写
	f.put('c'); //写入一个字符
}

四、Windows API处理文件

如果是在windows系统,那么还可以直接调用系统api完成文件读写操作

但会更加复杂

需要头文件:

#include<Windows.h>

首先是打开文件的函数:CreateFileA或CreateFileW

HANDLE CreateFileA(
LPCSTR lpFileName, //要打开的文件名
DWORD dwDesiredAccess, //访问文件权限
DWORD dwShareMode, //文件共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //安全模式,一般填0,默认
DWORD dwCreationDisposition, //打开方式
DWORD dwFlagsAndAttributes, //打开文件的属性和标志,一般为FILE_ATTRIBUTE_NORMAL
HANDLE hTemplateFile //模板文件句柄,一般为NULL
);

然后读文件函数:ReadFile

BOOL ReadFile(
HANDLE       hFile, //要读取的文件句柄,CreateFileA的返回值,相当于c中的FILE
LPVOID       lpBuffer, //存储读取内容的缓存区
DWORD        nNumberOfBytesToRead, //要读取的字节数
LPDWORD      lpNumberOfBytesRead, //接收读到的字节数
LPOVERLAPPED lpOverlapped //重叠结构,一般填NULL
);

还有写文件函数:WriteFile

BOOL WriteFile(
HANDLE       hFile,//要写入的文件句柄,CreateFileA的返回值,相当于c中的FILE
LPCVOID      lpBuffer,//要写入文件的缓存区
DWORD        nNumberOfBytesToWrite, //要写入的字节数
LPDWORD      lpNumberOfBytesWritten, //接收已经写入的字节数
LPOVERLAPPED lpOverlapped //重叠结构,一般填NULL
);

最后是关闭文件函数:CloseHandle

BOOL CloseHandle(
HANDLE hObject  //要关闭的文件句柄
);

示例:

#include<Windows.h>
int main() {
	HANDLE hFile=CreateFileA("1.txt", GENERIC_READ | GENERIC_WRITE,0,0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); //打开读写模式打开文件
	if (hFile == NULL) { //打开文件失败,退出
		return -1;
	}
	DWORD len;
	WriteFile(hFile,"test",sizeof("test"),&len,NULL); //写文件
	char buf[0xFF];
	ReadFile(hFile,buf,0xFF,&len,NULL); //读文件
	CloseHandle(hFile);//关闭文件
}

五、ATL处理文件

如果你觉得直接使用win API操作文件太麻烦,那就可以尝试自己将其封装一个类

而ATL就帮我们把这一个工作给做了,在VS环境下,可以直接包含这个头文件:

#include<atlfile.h>

该头文件中有一个CAtlFile类,就是简洁的将上面的win API函数封装了一下

其使用方式比win API会简洁很多

#include<atlfile.h>
int main() {
	CAtlFile file;
	file.Create(L"text.txt", GENERIC_ALL, 0, CREATE_NEW);
	char buf[20] = "hello world";
	file.Write(buf, 20);
	file.Read(buf, 20);
	file.Close();
}

正如你所看到的,它仅仅只是简单的封装了一下,其参数依旧是win API对应的参数,需要经常查询文档

其优点就是提高了我们的开发速度,而且最终生成的目标程序与直接使用win API进行开发相差不大

总结

如果你希望提高开发速度,跨平台,那么我推荐你使用C++方式

如果在意目标程序的大小,但想要跨平台,那么我推荐你使用C方式

如果你只是想要在windows平台开发程序,很在意程序的大小,那么我就推荐你使用win API

在此基础上如果你还想要提高开发速度,那么就可以使用一下ATL里面封装好的文件类

想要深入学习C/C++的同学,可以点击下方链接查看一份详细的C/C++教程,以项目为主导,从入门到精通!文章来源地址https://www.toymoban.com/news/detail-512528.html

C/C++实战入门到精通 https://blog.csdn.net/weixin_50964512/article/details/125710864

到了这里,关于C/C++文件读写(最全方法,多种实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java文件复制多种方法

    1、InputStream与OutputStream  创建两个文件 - 源和目标。然后我们从源创建InputStream并使用OutputStream将其写入目标文件进行 java 复制文件操作。 2、Apache Commons IO FileUtils copyFile(File srcFile, File destFile)可用于在 java 中复制文件。如果您已经在项目中使用 Apache Commons IO,那么使用它来简

    2024年02月06日
    浏览(32)
  • 前端:下载文件(多种方法)

    一、简介 前端经常会有下载文件的需求,这里总结了几种常用的方法,方便日后查看。 二、a标签下载 a href=\\\"https://abc.png\\\" download=\\\"abc.png\\\" target=\\\"view_window\\\"下载/a 三、window.open下载 四、location.href 五、saveAs 六、loadFileSimply 6.1、loadFileSimply 6.2、fileDownload 6.3、使用 七、url下载 八、

    2024年02月13日
    浏览(38)
  • 自然语言处理实战项目17-基于多种NLP模型的诈骗电话识别方法研究与应用实战

    大家好,我是微学AI,今天给大家介绍一下自然语言处理实战项目17-基于NLP模型的诈骗电话识别方法研究与应用,相信最近小伙伴都都看过《孤注一掷》这部写实的诈骗电影吧,电影主要围绕跨境网络诈骗展开,电影取材自上万起真实诈骗案例。随着科技的快速发展,诈骗电

    2024年02月09日
    浏览(58)
  • Linux 统计文件数量:多种方法全面掌握

    你是否想过在 Linux 系统中如何快速地统计某个目录下文件的数量?作为 Linux 用户,这是一个很常见的需求。无论是进行系统维护,还是管理文件,我们都需要掌握这个技能。在本文中,我们将向你介绍多种不同的方法来实现这个目标。 统计目录中的文件数量 统计目录中文件

    2024年02月16日
    浏览(45)
  • 修改 Windows 文件访问权限的多种方法

    提示:本文修改后包含编程方法以及附注的工具方法,传统的资源管理器交互方法等等。 由于文件是安全对象,因此访问它们受访问控制模型控制,该模型控制对 Windows 中所有其他安全对象的访问。  更改文件或目录对象的安全描述符,需要调用 SetNamedSecurityInfo 或 SetSec

    2024年02月05日
    浏览(36)
  • 在Linux中创建文件的多种方法

    在Linux系统中,文件的创建是日常操作中不可避免的一部分。无论是创建空文件、编辑文本文件还是生成特定内容的文件,Linux提供了多种工具和命令来满足用户的需求。本文将介绍几种常用的文件创建方法。 使用重定向符号 “” 是最简单而直接的创建文件的方法之一。通过

    2024年01月20日
    浏览(42)
  • 【Linux】CentOS7操作系统安装nginx实战(多种方法,超详细)

    大家好,又见面了,我是沐风晓月,本文是专栏【运维系列-架构与服务】专栏中的[linux基本功-系统服务实战篇],主要讲解nginx的编译安装和yum安装的方式 此专栏是沐风晓月对Linux常见的服务和架构进行总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。 如果

    2024年02月02日
    浏览(53)
  • 2023年最新最全uniapp入门学习,零基础入门uniapp到实战项目,unicloud数据后台快速打造uniapp小程序项目

    今天开始带着大家一起零基础学习uniapp,在下面的课程中我们就简称uniapp为uni吧。我这里从零基础开始教大家,后面可以带大家简单的做一个实战项目。所以不用担心自己没有基础,跟着石头哥认真学习就行了的。 我们学习uniapp之前先要认识uniapp的好处 看下官网 https://unia

    2024年02月06日
    浏览(46)
  • Linux中文件名修改的多种方法

    找一个不算漂亮的普通女孩,一起柴米油盐,一起日出日落,一起田间地头,一起春花冬雪!要一个不算大的小房子,生两个健康可爱的宝宝,这样就很好。。。。。。 简介: 在Linux系统中,通过命令行界面可以方便地修改文件名。本篇博客将介绍几种常见的方法,包括 m

    2024年01月18日
    浏览(40)
  • 如何在macbook上删除文件?Mac删除文件的多种方法

    在使用MacBook电脑时,桌面上经常会积累大量的文件,而这些文件可能已经不再需要或已经过时。为了保持桌面的整洁和提高电脑性能,我们需要及时删除这些文件。本文将介绍MacBook怎么删除桌面文件,以及macbook删除桌面文件快捷键。 一、macbook怎么删除桌面文件 在MacBook上删

    2024年02月03日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包