C/C++中进行文件读写的方法

在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(本文采用)、callocrealloc,略有区别(可以参考一下这位大佬的博客: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);
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值