C++文件 I/O操作

2023-10-29

文件流类和文件流对象

输入输出是以系统指定的标准设备(标准设备:输入设备为键盘,输出设备为显示器)为对象。在实际的开发中,不可避免会以磁盘文件作为对象。即从磁盘文件读取数据,将数据输出到磁盘文件。

与文件输入输出有关的类主要定义在fstream.h头文件中,这个头文件主要包含了三个类,由这三个类控制对文件的各种输入输出操作。ifstream、ofstream、fstream。

由于文件设备不像显示器屏幕与键盘那样是标准默认设备,所以它在fstream.h头文件中式没有像cout那样预先定义的全局对象,所以我们必须自己定义一个该类的对象。

 ifstream类:从istream派生的,用来支持从磁盘文件输入

ofstream类:从ostream派生的,用来支持从磁盘文件输出

  fstream类:从iostream派生的,用来支持对磁盘文件的输入输出


C++文件的打开与关闭

打开文件:

所谓打开(open)文件是一种形象的说法,如同打开房门就可以进入房间活动一样。打开文件是指在文件读写之前做必要的准备工作。包括:

1).为文件流对象和指定的磁盘文件建立关联,以便使文件流流向指定的磁盘文件

2).指定文件的工作方式.如:该文件是作为输入文件还是输出文件,是ASCII文件还是二进制文件等

以上工作可以通过两种不同的方法实现:
1)调用文件流的成员函数open

        ofstream outfile;                                //定义ofstream类(输出文件流类)对象outfile

        outfile.open("f1.dat",ios::out);           //使文件流与f1.dat文件建立关联

        ios::out是I/O模式的一种,表示以输出方式打开一个文件,或者简单地说,此时f1.dat是一个输出文件,接收从内存输出的数据

2)在定义文件流对象时指定参数

        在声明文件流类时定义了带参数的构造函数,其中包含了打开磁盘文件的功能。因此,可以在定义文件流对象时指定参数,调用文件流对象的构造函数来实现打开文件的功能,

        ostream outfile("f1.dat",ios::out);一般用此方式,比较方便

        作用与open函数相同,输入输出方式是在ios类中定义的,它们是枚举常量,有多种选择

方式 作用
ios::in 以输入方式打开文件
ios::out 以输出方式打开文件(这是默认方式),如果文件有内容,则先全部清除
ios::app 以输出的方式打开文件,写入的数据添加在文件末尾
ios::ate 打开一个已有的文件,文件指针指向文件末尾
ios::trunc 打开一个文件,如果文件已存在,则删除其中全部数据,如果文件不存在,则建立新文件。
ios::binary 以二进制方式打开一个文件(方便以块的方式读写文件)
ios::nocreate 打开一个已有的文件,如果文件不存在,则打开失败
ios::noreplace 如果文件不存在则创建新文件,如果文件已存在则操作失败

几点说明:

        1)新版本的I/O类库中不提供ios::nocreate 和 ios::noreplace

        2)每一个打开的文件都有一个文件指针,该指针的初始位置由I/O方式指定,每次读写都从文件指针的当前位置开始。每读入一个字节,指针就后移一个字节。当文件指针移动到最后,就会遇到文件结束EOF(文件结束符要占用一个字节,其值为   -1)。此时流对象的成员函数eof的值为非0值,表示文件结束。  【fp.eof()!=0】

        3)可以用“位或”运算符“|”对输入输出方式进行组合

            ios::in | ios::noreplace

        4)如果打开操作失败,open函数的返回值为0,如果是调用构造函数的方式打开文件的,则流对象的值为0

           if(outfile.open("f1.dat",ios::app) == 0)   {cout<<"open error"<<endl;}

           if(!outfile.open("f1.dat",ios::app) == 0)  {cout<<"open error"<<endl;}

关闭文件:

 在对已打开的磁盘文件的读写操作完成后,应关闭该文件。关闭文件用成员函数close【outfile.close()】。所谓的关闭,实际上是解除该磁盘文件与文件流的关联,原来设置的工作方式也失效,这样就不能通过文件流对该文件进行输入或输出。


C++对ASCII文件的读写操作

如果文件每一个字节中均以ASCII代码形式存放数据(字符文件)

1)用流插入运算符“<<”和流提取运算符">>"输入输出标准类型的数据。"<<"和">>"都已在iostream中被重载为能用于ostream和istream类对象的标准类型的输入输出。由于ifstream和ofstream分别是ostream和istream类的派生类,因此它们从ostream和istream类继承了公用的重载函数,所以在对磁盘文件的操作中,可以通过文件流对象和流插入运算符"<<"及流提取运算符">>"实现对磁盘文件的读写。

2)用文件流的put、get、getline等成员函数进行字符输入输出操作

3)ostream是ofstream的基类,所以ostream中的公有成员函数在ofstream对象也可以用。istream与ifstream同理。

#include <iostream>
#include <fstream>
using namespace std;

int main(void)
{

    char fileName[80];
    char buffer[256];

    cout<<"请输入一个文件名:";
    cin>>fileName;

    ofstream fout(fileName,ios::app);  //以追加的方式打开不存在则创建一个
    fout<<"111111\n";
    fout<<"222222\n";

    //cin.getline(buffer,256);   //从键盘键入
    cin>>buffer;
    fout<<buffer<<endl;
    fout.close();

    ifstream fin(fileName,ios::in);
    char ch;
    while (fin.get(ch))
    {
        cout<<ch;
    }
    
    fin.close();


    return 0;
}

补充:

        ofstream::ofstream(constchar *filename,int mode = ios::out,int                                                 penprot=filebuf::openprot);

        filename:要打开的文件名

        mode:打开文件的方式

        penprot:打开文件的属性

属性 含义
0 普通文件,打开访问
1 只读文件
2 隐含文件
4 系统文件

可以用"或"或者”+“把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。由于fstream类可以对文件同时进行读写操作,所以对它的对象进行初始化的时候一定要显示的指定mode和openprot参数。


 C++对二进制文件的读写操作

        二进制文件不是以ASCII代码存放数据的,它将内存中数据存储形式不加转移地传送到磁盘文件,因此它又称为内存数据的映像文件。因为文件中的信息不是字符数据,而是字节中的二进制形式信息,因此字节文件。

        对二进制文件的操作也需要先打开文件,用完后要关闭文件。在打开时要用ios::binary指定以二进制形式传送和存储。二进制文件除了可以输入文件或输出文件外,还可以是既能输入又能输出的文件。

 用成员函数read和write读写二进制文件

 对二进制文件的读写主要用fstream类成员函数read和write来实现。这两个成员函数的原型为:

istream& read(char *buffer,int len);
ostream& write(const char* buffer,int len); 

//buffer是字符指针,指向内存中一段内存空间
//len是读写的字节数
#include <iostream>
#include <fstream>
using namespace std;

class Teacher 
{
public:
    Teacher(int age,const char *name)
    {
        this->age  = age;
        this->name = name;
    }
    void prinT()
    {
        cout<<age<<"   "<<name<<endl;
    }
public:
    int     age;
    const char*   name;

};

int main(void)
{

    char fileName[255]="file.txt";
    ofstream fout(fileName,ios::binary);

    if(!fout)
    {
        cout<<"Unable to open"<<fileName<<endl;
        return -1;
    }

    Teacher t1(31,"31");
    Teacher t2(32,"32");

    fout.write((char *)&t1,sizeof(Teacher));
    fout.write((char *)&t2,sizeof(Teacher));
    fout.close();

    cout<<"保存对象到二进制文件里成功"<<endl;

    ifstream fin(fileName,ios::binary);
    if(!fin)
    {
        cout<<"Unable to open"<<fileName<<endl;
        return -1;
    }

    Teacher tmp(100,"100");
    fin.read((char *)&tmp,sizeof(Teacher));
    tmp.prinT();



    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++文件 I/O操作 的相关文章

  • 预加载整个模型以估计 Tensorflow Serving 的内存消耗

    当执行预测时 Tensorflow Serving 延迟初始化模型 DAG 中的节点 这使得很难估计保存整个模型所需的内存 RAM 是否有一种标准方法可以强制 Tensorflow Serving 将模型完全初始化 加载到内存中 您可以使用
  • 反序列化 GUID 数组时出现 JSON.NET 异常

    我正在使用 JSON NET 反序列化从浏览器发送的 AJAX HTTP 请求 并且在使用 Guid 作为参数的 Web 服务调用时遇到问题 当我使用内置的 NET 序列化器时 这工作得很好 首先 流中的原始字节如下所示 System Te
  • 信用卡号应该存储为字符串还是整数?

    是啊 只是想想而已 我应该将在我的网站上输入的信用卡号存储为字符串还是整数 我的意思是 它们由数字组成 这让我认为它是一个整数 但我不对它们进行数学运算 所以也许字符串更合适 编辑 所以我必须在加密之前存储在某个时刻输入的数字 我可能应该更
  • 替换大字符串中的多个字符串的最快方法

    我正在寻找替换大 1mb 字符串的多个 500 子字符串的最快方法 无论我尝试过什么 String Replace 似乎都是最快的方法 我只关心最快的方式 不是代码的可读性 可维护性等 我不在乎是否需要使用不安全的代码或预处理原始字符串 每
  • 在 SelectSingleNode 中使用 XPath:从 XML 中检索单个元素(如果存在)

    我的 XML 看起来像
  • 如何使用仿函数作为类模板中的成员?

    我试图使用函子作为std function类模板内的对象 以下是我到目前为止所做的事情 the functor class template template
  • 在 C 中使用模板函数的最短示例?

    我如何处理函数echo tpl可以采取1类型参数int or string 然后打印出来 C没有模板 我认为你能做的最好的事情就是使用联合或让函数具有不同的名称 后一种具有不同名称的方法是准标准方法 例如fabs fabsf fabsl a
  • 如何向 Iron Python 添加模块?

    我一直在尝试使用 C Visual Studio 执行以下 Python 代码 graphcreater py 我通过 NuGet 包管理器添加了 IronPyton 2 7 7 和 IronPython StdLib 2 7 7 一旦我运
  • C# 中的 memcpy 函数 [重复]

    这个问题在这里已经有答案了 可能的重复 C memcpy 等效项 https stackoverflow com questions 510971 c memcpy equivalent 相当于什么memcpyC 中的函数 正如已经说过的
  • 为什么 VS 2008 在 Intellisense 中不显示 String 类的扩展方法

    由于 String 实现了IEnumerable
  • “#include ”导致“错误:asm/io.h:没有这样的文件或目录”

    我正在使用 gentoo 并尝试编译一个程序来控制并行端口上的位 它的顶部附近有这一行 include
  • 对双向链表进行排序 C++

    尝试通过遍历列表的循环来完成此操作 在循环中 我将头节点输入到我定义的排序函数中 然后使用 strcmp 来确定节点中的哪个名称是否应该排在前面 它不起作用 因为写得太早了 我通过一次沿着列表一个节点进行线性比较 而不是回去查看第一个节点是
  • 网页上的富文本编辑器

    我正在尝试在我的网页中添加一个富文本编辑器 用户可以在其中撰写评论并格式化他们所写的内容 类似于我们在此网站上撰写帖子的编辑器 谁能指出我关于此的正确方向 任何可以帮助我构建这样一个组件的教程 我还想要一个免费的产品 忘记之前提到 类似的东
  • C# 中的任意精度小数?

    是否存在任意精度decimal类可用于 C 吗 我见过几个任意精度整数类 但这并不完全相同 您可以使用 J 库java math BigDecimal类 如果已安装 只需添加一个引用即可vjslib me remembers one of
  • Microsoft Build Tools 2013 缺少 v120 目录

    我们已经安装了 Microsoft Build Tools 2013 从http www microsoft com en us download details aspx id 40760 http www microsoft com e
  • 传递给 WCF 服务的可选查询字符串参数

    我想知道如何使用 string limit WebOperationContext Current IncomingRequest UriTemplateMatch QueryParameters Limit 在我的wcf中这个方法 Cit
  • 如何隐藏鼠标光标?

    我想问是否有人可以为我提供一个 C 代码 在其中我可以在按下特定键时隐藏 显示鼠标指针 我发现一些只为 TURBO C 编写的代码 它们都不能使用 dev c 甚至 Visual c 编译和运行 我尝试运行在 Dev C 中找到的代码 但我
  • C++ 中的 golang 风格“延迟”[重复]

    这个问题在这里已经有答案了 我正在阅读有关 go 语言的defer http blog golang org defer panic and recover陈述 它允许您指定函数结束时要执行的操作 例如 如果您有一个文件指针或资源 则只需指
  • 将用户控件绑定到 bool 属性的相反值

    非常简单 我想做同样的事情this https stackoverflow com questions 534575 how do i invert booleantovisibilityconverter但在winforms中 谷歌似乎提
  • 使用 CRTP 模式时继承中的不明确方法

    我正在定义一个DoubleWrapper类继承自两个 CRTP 基类 Ratioable and Divable 两者都定义operator 具有不同的签名 T operator double const scalar const retu

随机推荐

  • 初学React,做一个简易的滚动加载

    想做一个简单的滚动鼠标加载更多商品的功能 虽然有相关插件更方便 不过想手写一个简易版的 我把这个板块放在最下方 再下面就是一个小小的底部导航了 所以就判断滚动到页面底部就行 判断滚动到底部需要知道3个值 滚动的高度 可视区域的高度 滚动条内
  • 概率图模型&概率模型 及其应用

    文章目录 概率图模型 有向 vs 无向 概率模型 参数估计 隐变量估计 变分推断 应用例子1 BM RBM 应用示例2 概率图模型中网络结构估计 概率图模型 有向 vs 无向 概率图模型用图刻画一组随机变量之间的相关关系 有向 无环 图刻画
  • STM32移植mbedtls实现AES加解密

    前言 在实际的物联网项目开发中 经常需要将设备采集到的数据远程传输到服务器端 设备也会接收远程服务器端下发过来的数据 这便是数据交互 如果这些数据只是通过明文方式 进行交互 那么是不安全的 那么就需要将数据进行加密和解密了 本文讲基于mbe
  • GLSurfaceView 的onDrawFrame()频繁调用

    可用GlSurfaceView setRenderMode GLSurfaceView RENDERMODE WHEN DIRTY 和 GlSurfaceView setRenderMode GLSurfaceView RENDERMODE
  • Netty UDP 使用采坑

    使用Netty搭建UDP服务收集日志 使用过程中发现 部分日志接收不到 排查发现 都是大日志记录不到 后查询相关文档进行如下修改 EventLoopGroup workerGroup new NioEventLoopGroup 20 try
  • 创建随机点使用支持向量机进行分类(Arcgis+Envi)

    独自摸索是比较痛苦的 每周末两天才能碰巧挖出一个点 希望这篇文章能对你有所帮助 话不多说直接进入正题 首先在arcgis中导入图片 可能遇到此类情况 解决办法如下 双击图片 symbology RGB三通道选择波带 stretch选择拉伸方
  • Java自带排序函数sort()的使用方法

    import java util Arrays class Solution public int sortedSquares int nums int nums1 new int nums length for int i 0 i lt
  • git命令创建,合并,删除分支代码

    创建分支 1 git branch test 创建一个test的分支 2 git checkout test 切换到test分支 3 git add 4 git commit m 提交代码的说明 5 git remote add origi
  • 645.错误的集合(力扣leetcode) 博主可答疑该问题

    一 笔记部分 思路 1 可以用排序 先排序后连续两个相同 还有那个位置上缺了就是那个 2 转化为负数 先遍历一次先将每个元素所对应位置的树转化为负数 然后再遍历一次看那个是负数 就是出现了两次 再看索引的数字是否为负数 因为出现了的都是为负
  • go_命令行参数Args、flag

    Args os Args是一个string的切片 可以存储所有的命令行参数 在终端运行才行 func main args os Args for i v range args fmt Println 索引 i t数据 v 既然是切片 那就可
  • 2022年iOS上架及证书最新申请流程

    最近的15年 手机行业无论怎么变 ios系统依然还是占据着行业的榜首位置 而打包一个苹果的app 门槛则比较高 主要的原因在于苹果app的开发 打包时需要p12格式的证书文件和描述文件profile文件 在hbuilder和apicloud
  • 关于串口助手接收到数据,但显示的数据(16进制)为00的解决方法

    只需要把波特率调低就行
  • 直流电机控制 pwm 和 pid 算法

    下面的文章是我转载的 所以作者若是看到不允许转载 请给我留言或给我邮件 lushiliangcsdn 163 com 我会立即删除 转载原因 这篇文章把pid 算法解释的很详细 我担心以后这篇文章无故删除 才转载到我这边的 谢谢 转载来源于
  • 错误代码57049处理

    DB2 SQLSTATE 57049 处理过程 错误代码57049 修改 etc services 修改实例参数db2inst1参数 错误代码57049 db2 connect to 数据库 后报 SQLSTATE 57049 错误 SQL
  • Ubuntu18.04 搭建ros环境

    目录 一 查询版本 二 配置Ubuntu软件库 三 安装 1 设置安装源和密钥 2 更新可用软件包列表 问题 问题 3 安装 4 初始化 问题 5 更新 6 添加环境变量 7 安装rosinstall 8 安装catkin编译器 9 实例测
  • U3D客户端框架之小堆顶高性能定时器测试10W计时器耗时1.9ms

    1 小顶堆计时器概要 小根堆定时器的优点如下 a 添加时间复杂度为O 1 b 删除时间复杂度为O 1 c 执行一个定时器的时间复杂度为O 1 2 代码设计 之前写的服务器定时器是全部轮询更新 这种计时器性能太差 每一帧都要全部迭代一次 客户
  • 全网最全的最通俗易懂的-jmeter调试错误全集

    一 前言 在使用jmeter做接口测试的过程中大家是不是经常会遇到很多问题 但是无从下手 不知道从哪里开始找起 对于初学者而言这是一个非常头痛的事情 这里结合笔者的经验 总结出以下方法 二 通过查看运行日志调试问题 写好脚本后 可以先试着运
  • 强化学习入门笔记

    学习情况 先后听了两门课程 分别是David Silver的RL和Sergey Levin的DRL 各耗时一周左右 后者更难一些 对RL基本概念 常用算法原理及其伪代码有了大致了解 但是因为时间有点赶 没有敲完整的算法代码 由于已经有写得比
  • vue每个生命周期的作用,以及在哪个阶段发请求,详解

    1 什么是vue生命周期 有什么作用 每个 Vue 实例在被创建时都要经过一系列的初始化过程 例如 需要设置数据监听 编译模板 将实例挂载到 DOM 并在数据变化时更新 DOM 等 同时在这个过程中也会运行一些叫做 生命周期钩子 的函数 这
  • C++文件 I/O操作

    文件流类和文件流对象 输入输出是以系统指定的标准设备 标准设备 输入设备为键盘 输出设备为显示器 为对象 在实际的开发中 不可避免会以磁盘文件作为对象 即从磁盘文件读取数据 将数据输出到磁盘文件 与文件输入输出有关的类主要定义在fstrea