在C++中进行文件读写有多种方法,在这里介绍其中的一种,只需要最基本的iostream头文件即可。
代码
#include <iostream>
using namespace std;
// 文件路径
const char* inPath = "...";
const char* outPath = "...";
int main()
{
// 文件指针
FILE* inFile;
FILE* outFile;
// 文件总字节数
int inFileSize;
int outFileSize;
// 打开文件
if (fopen_s(&inFile, inPath, "rb") == 0)
{
cout << "Successfully opened the original file." << endl;
}
else
{
cout << "Failed to open the original file." << endl;
}
// 被标记为“不安全”的方法
/* if ((inFile = fopen(inPath, "rb")) == NULL)
{
cout << "Failed to open the original file." << endl;
}
else
{
cout << "Successfully opened the original file." << endl;
} */
// 计算文件总字节数
fseek(inFile, 0L, SEEK_END); // 使文件指针指向文件末尾
inFileSize = ftell(inFile); // 文件总字节数
rewind(fp); // 再使文件指针指回文件起始
// 建立缓冲区
// 方法1(C++)
unsigned char* inBuffer = new unsigned char[inFileSize];
unsigned char* outBuffer = new unsigned char[outFileSize];
// 方法2(C/C++)
// unsigned char* inBuffer = (unsigned char*)malloc(inFileSize);
// unsigned char* outBuffer = (unsigned char*)malloc(outFileSize);
// 将数据读入缓冲区
fread(inBuffer, sizeof(unsigned char), inFileSize, inFile);
// 对outBuffer进行处理……
// 将处理后的数据写入新文件
fwrite(outBuffer, sizeof(unsigned char), outFileSize, outFile);
//格式化输出到文件
fprintf(outFile, "Hello world!");
// 关闭文件
fclose(inFile);
fclose(outFile);
// 释放内存
// 对应new的方法
delete[]inBuffer;
delete[]outBuffer;
// 对应malloc的方法
// free(inBuffer);
// free(outBuffer);
}
说明
文件路径
文件路径一般建议使用绝对路径。
在Windows中,文件路径名中的“\”需要手动改为“\\”,macOS文件路径的“/”不需要作修改。
fopen_s函数
-
功能:打开文件
-
函数原型:
errno_t fopen_s(FILE** _Stream, const char* _FileName, const char* _Mode); -
参数:
-
_Stream:文件指针;对应的实参写法应为&_Stream -
_FileName:文件名称(路径) -
_Mode:访问方式(常用访问方式如下表所示;后缀b表示以二进制的方式打开)访问方式 含义 "r"/"rb"只读:打开一个已有的文件 "w"/"wb"只写:打开一个空文件进行写入(若该文件存在则会被覆盖) "a"/"ab"追加:打开一个文件进行追加写入(若文件不存在将会新建该文件) "r+"/"rb+"读写:对一个已有的文件进行读或写 "w+"/"wb+"只读:打开一个空文件进行读写(若该文件存在则会被覆盖) "a+"/"ab+"读+追加:打开一个文件进行读取和追加写入(若文件不存在将会新建该文件)
-
-
返回值:
0表示读取成功,其他情况均表示读取失败(但含义各有不同,在此不一一列举) -
有关
fopen函数:函数原型为FILE fopen(const char* _FileName, const char* _Mode);,用法与fopen_s类似(但返回值为NULL表示读取失败)。但在Visual Studio中进行C++的编译会出现C4996错误:
fopen编译报错这是由于该函数被标记为不安全的CRT库函数,因此建议使用更安全的
fopen_s函数代替。若仍要使用,转到菜单栏 → 项目 → 属性,点击属性配置 → C/C++ → 预处理器,在预处理器定义中添加一项_CRT_SECURE_NO_WARNINGS(如图),或在代码中添加一行#define _CRT_SECURE_NO_WARNINGS即可消除掉该报错。
消除C4996错误
fseek函数
-
功能:重新定位文件指针的指向
-
函数原型:
int fseek(FILE* _Stream, long _Offset, int _Origin); -
参数:
-
_Stream:文件指针 -
_Offset:(长整型)相对于_Origin的偏移量(正数表示正向偏移,负数反之) -
_Origin:偏移量的参考基准。可取值为:偏移基准 含义 SEEK_SET(或0)文件起始 SEEK_CUR(或1)文件当前位置 SEEK_END(或2)文件结尾
-
-
例如
fseek(fp, -100L, SEEK_END);表示将文件指针退回到距离文件结尾100字节处 -
rewind(fp)功能也是文件指针的定位,只不过是定位到文件起始,相当于fseek(fp, 0L, 0);
ftell函数
- 功能:返回文件指针当前位置(用相对于文件起始的偏移量表示)
- 函数原型:
long ftell(FILE* _Stream);
动态分配内存
在C中,动态分配内存的方式有三种:malloc(本文采用)、calloc、realloc,略有区别(可以参考一下这位大佬的博客:C/C++动态内存分配),对应地,释放内存使使用free函数;C++中该方法仍然可用,也可以使用new标识符进行内存分配,在释放内存时,相应使用delete[]。
fread/fwrite函数
- 功能:读/写数据块
- 函数原型:
size_t fread(void* _Buffer, size_t _ElementSize, size_t ElementCount, FILE* _Stream);(fwrite完全相同) - 参数:
_Buffer:数据块的首地址(例如缓冲区指针名)_ElementSize:每个要读/写地数据块的字节数_ElementCount:要读/写的数据块数(在功能上,只要保证_ElementSize和_ElementCount的乘积正确即可)_Stream:要读/写的文件指针
- 返回值:成功读取的数据块数(可以用来输出并检查错误)
fprintf函数
- 功能:格式化输出到指定流文件
- 函数原型:
int fprintf(FILE* _Stream, const char* _Format, [argument]); - 参数:第一个参数为要输出的文件的文件指针,其余参数与
printf函数完全相同 - 返回值:读取成功,返回I/O的个数;出错或文件尾,返回
EOF - 类似地,也有
fscanf函数,具体用法不再赘述
fclose函数
- 功能:关闭文件
- 函数原型:
int fclose(FILE* _Stream);
本文详细介绍C++中使用fopen_s、fseek、ftell等函数进行文件读写的具体步骤,包括文件打开、计算文件大小、数据读取与写入、格式化输出及资源释放的全过程。
1457

被折叠的 条评论
为什么被折叠?



