【C++知识点】文件操作

news2024/11/25 19:16:26

✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:C/C++知识点
📣专栏定位:整理一下 C++ 相关的知识点,供大家学习参考~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
🎏唠叨唠叨:在这个专栏里我会整理一些琐碎的 C++ 知识点,方便大家作为字典查询~

文件操作

数据流的概念

数据流(data stream)是一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。

c++通过一种称为流(stream)的机制提供了更为精良的输入和输出方法。流是一种灵活且面向对象的I/O方法。

根据操作对象不同分为文件流、字符串流、控制台流

控制台流

C++输入输出操作分别是由istream(输入流)和ostream(输出流)这两个类提供的,为了允许双向的输入/输出,由istream和ostream派生出了iostream类。

类的继承关系如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xWMRMCpu-1678409502954)(C++笔记.assets/image-20221227092631025.png)]

是一种多继承的关系,在程序应用可以只包含头文件iostream。

上面的<<和>>操作符,是因为iostream.h头文件中,ostream类对应每个基本数据类型都有其友元函数对左移操作符进行了友元函数的重载。

文件流

文件流的输入输出类在fstream头文件被定义,和控制台流继承关系为:

由于文件设备不像显示器屏幕和键盘那样标准的默认设备,所以我们定义一个流对象。

ofstream类的默认构造函数原形为:

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

mode属性表:

打开文件属性值:

“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。文件使用完后可以使用close成员函数关闭文件。

ios::app为追加模式,在使用追加模式的时候同时进行文件状态的判断是一个比较好的习惯。

字符串流

字符串流就是能够控制字符串类型对象进行输入输出的类,C++不光可以支持C++风格的字符串流控制,还可以支持C风格的字符串流控制。

继承关系如下图:

类型解释
istrstreamC风格的串流的输入操作,字符串数组作为输入。
ostrstreamC风格的串流的输出操作,字符串数组作为输出。
strstream支持C风格的串流的输入输出操作。

文件处理简介

c++的文件处理也是看为一个对象,使用文件流的类,使用头文件,处理的时候有文本文件和二进制文件之分,主要的区别就是存储的形式。

C++ 通过以下几个类支持文件的输入输出:

  • ofstream: 写操作(输出)的文件类 (由ostream引申而来)
  • ifstream: 读操作(输入)的文件类(由istream引申而来)
  • fstream: 可同时读写操作的文件类 (由iostream引申而来)

要在 C++ 中进行文件处理,必须在 C++ 源代码文件中包含头文件 <iostream><fstream>

文件处理基本流程:

文件的输入与输出

打开文件

在从文件读取信息或者向文件写入信息之前,必须先打开文件。

ofstream 和 fstream 对象都可以用来打开文件进行写操作,如果只需要打开文件进行读操作,则使用 ifstream 对象。

下面是 open() 函数的标准语法,open() 函数是 fstream、ifstream 和 ofstream 对象的一个成员。

void open(const char *filename, ios::openmode mode);

open() 成员函数的第一参数指定要打开的文件的名称和位置,第二个参数定义文件被打开的模式。

可以把以上两种或两种以上的模式结合使用。例如,如果想要以写入模式打开文件,并希望截断文件,以防文件已存在,那么可以使用下面的语法:

ofstream outf;
outf.open("file.txt", ios::out | ios::trunc );

如果想要打开一个文件用于读写,可以使用下面的语法:

fstream file;
file.open("file.txt", ios::out | ios::in );

ofstream, ifstream 和 fstream所有这些类的成员函数open 都包含了一个默认打开文件的方式,这三个类的默认方式各不相同:

写入与读取
  • 写入文件

    在 C++ 编程中,可以使用流插入运算符( << )向文件写入信息,就像使用该运算符输出信息到屏幕上一样。唯一不同的是,在这里使用的是 ofstream 或 fstream 对象,而不是 cout 对象。

  • 读取文件

    在 C++ 编程中,可以使用流提取运算符( >> )从文件读取信息,就像使用该运算符从键盘输入信息一样。唯一不同的是,在这里使用的是 ifstream 或 fstream 对象,而不是 cin 对象。

关闭文件

当 C++ 程序终止时,它会自动关闭刷新所有流,释放所有分配的内存,并关闭所有打开的文件。但写程序时应该养成一个好习惯,在程序终止前关闭所有打开的文件

下面是 close() 函数的标准语法,close() 函数是 fstream、ifstream 和 ofstream 对象的一个成员。

void close();
案例 - 写入

每次运行都会覆盖原来的内容:

#include <iostream>
#include <fstream> //1.头文件
using namespace std;

int main() 
{
    //2.创建流对象
    ofstream outf; 
    
    //3.打开文件
    outf.open("file.txt"); 
    //outf.open("file.txt",ios::out);
    //outf.open("file.txt",ios::app);	//每次运行不会覆盖原来内容
    
    //4.写入内容
    outf << " 山村咏怀" << endl;
    outf << " 邵雍" << endl;
    outf << "一去二三里,烟村四五家。" << endl;
    outf << "亭台六七座,八九十枝花。" << endl;
    
    //5.关闭文件
    outf.close();
    
    return 0;
}
案例 - 读取
#include <iostream>
#include <fstream> //文件流的头文件 
using namespace std;
int main() 
{
    //char cf[100]; //字符数组
    string cf; //字符串
    ifstream infile;
    infile.open("file.txt",ios::in); //inf.open("file.txt");
    infile >> cf;
    infile.close();
    cout << cf;
    return 0;
}

在c++中使用ifstream读文件的时候会以空格为分隔符,遇到空格就不读取了。这时候可以调用get函数来读取内容。

#include <iostream>
#include <fstream> //文件流的头文件 
using namespace std;
int main() 
{
    char a
    ifstream infile; //定义ifstream类(输入文件流类)对象infile
    infile.open("file.txt"); //打开文件 使文件流与c++.txt文件建立关联
    while (!infile.eof()) 
    {
        infile.get(a); //依次获取文件中每个字符 并输出 
        cout << a;
    }
    infile.close();
    return 0;
}

其实读取方式分为很多种,每种方式效率不同:

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main()
{
    ifstream ifs;
    ifs.open("file.txt", ios::in);
    
    //判断是否打开
    if (!ifs.is_open())
    {
        cout << "文件打开失败!" << endl;
        return 0;
    }
    
    //读数据
    //第一种:效率低,不建议使用
    /*char c;
    while ((c = ifs.get()) != EOF)
    {
    	cout << c;
    }*/
    
    //第二种
    /*char buf[1024] = {0};
    while (ifs >> buf)
    {
    	cout << buf << endl;
    }*/
    
    //第三种
    /*char buf[1024] = {0};
    while (ifs.getline(buf, sizeof(buf)))
    {
    	cout << buf << endl;
    }*/
    
    //第四种
    string buf;
    while (getline(ifs,buf)) //getline函数需要#include <string>
    {
        cout<<buf<<endl;
    }
    
    ifs.close();
    return 0;
}

二进制文件读写

写文件

二进制写文件主要利用流对象调用成员函数 write()

函数原型:

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

参数解释:字符指针buffer指向内存中的一段存储空间,len是读写的字节数

案例:

#include <iostream>
#include <fstream>
using namespace std;
class Student 
{
public:
    Student() {}
    Student(string name,int age) :name(name), age(age) {}
protected:
    string name;
    int age;
};
int main() 
{
    ofstream bof;
    Student s1("张三", 100);
    bof.open("student.txt", ios::out|ios::binary);
    bof.write((const char*) & s1, sizeof(Student));
    bof.close();
    return 0;
}
读文件

二进制读文件主要利用流对象调用成员函数 read()

函数原型:

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

参数解释:字符指针buffer指向内存中的一段存储空间,len是读写的字节数

案例:

ifstream bif;
bif.open("student.txt", ios::in | ios::binary);
if (!bif.is_open()) 
{
    cout << "文件打开失败" << endl;
    return 0;
}
Student s2;
bif.read((char*)&s2, sizeof(Student));
cout << s2.name << " " << s2.age << endl;
bif.close();

fstream文件操作

ifstream支持>>操作,ofstream支持<<操作,fstream同时支持>>和<<操作。

打开文件 fstream可以在声明流对象时传入文件名打开文件,也可以使用open()函数打开文件。

关闭文件 文件打开后必须关闭,fstream提供close()函数关闭文件。

打开文件

使用构造函数声明对象时打开文件,示例:

fstream file(filename, ios::in | ios::out);

使用open()函数打开文件,函数原型:

void open(const char* filename,int mode,int access);

如果只传入文件名,系统会自动根据文件类型选择默认的打开模式。

打开文件模式mode如图:

模式和属性可以单独使用,也可以混合使用。混合使用时,用逻辑连接符或 |连接。

ios::out模式默认会清空,即ios::out|ios::trunc和ios::out打开文件时都会清空文件。

如果不想清空文件,那么设置读写模式为ios::out|ios::app,以这种模式打开文件后,数据会以追加的方式写入到文件。

读写文件

fstream提供的读写操作有:<<、>>、read()、write()、put()、get()、getline()。根据文件类型可分为文本文件和二进制文件,根据读写方式可分为逐行读写和整块读写。通常,文本文件使用逐行读写的方式,二进制文件使用整块读写的方式。

  1. 文本文件读写

    逐行写入文本文件可以使用操作符====<<。

    逐行读取文本文件时可以使用==getline()==函数。

  2. 二进制文件的读写

    二进制文件通常整块读取或写入,当然也可以读写单个字符,用到的函数包括:put()、get()、read()、write()。

    通常使用write()、put()函数写入二进制文件。使用read()、get()读取二进制文件。

案例

#include <iostream>
#include <fstream> //1.包含头文件
#include <string>
using namespace std;
int main() 
{
    string str;
    fstream iofile; //2.创建对象
    iofile.open("file.txt",ios::out|ios::in|ios::trunc); //3.打开文件
    iofile << "这里是写入内容测试" << endl; //4.写入数据
    iofile << "this is test" << endl;
    iofile.close(); //5.关闭文件
    cout << "写入完毕" << endl;
    iofile.open("file.txt", ios::out | ios::in);
    while (getline(iofile,str)) //循环读取
    {
        cout << str << endl;
    }
    iofile.close();
    cout << "读取完毕" << endl;
    return 0;
}

文件定位和大小

C++的文件定位分为读位置和写位置的定位,对应的成员函数分别为seekg()和seekp()。seekg()函数设置读位置,seekp()设置写位置。函数原型如下:

istream& seekg(streamoff offset,seek_dir origin);   
ofstream& seekp(streamoff offset,seek_dir origin);

offset表示偏移量,seek_dir表示移动的基准位置,取值如下:

取值解释
ios::beg文件开头
ios::cur文件当前位置
ios::end文件结尾

示例:

inFile.seekg(2,ios::beg); // 把文件读指针从开始位置向后移动2个字节
outFile.seekp(2,ios::cur); // 把文件写指针从当前位置向后移动2个字节

获取文件大小可以使用seekg()和tellg()或者seekp()和tellp()函数结合使用的方式获取文件大小。

示例:

inFile.seekg(0,ios::end); // 读文件指针移动到文件末尾
streampos ipos = inFile.tellg()//返回当前指针的位置,也就是文件的大小,单位是字节

由此,我们可以对文件大小进行计算:

#include <iostream>
#include <fstream>
using namespace std;
int main(){ 
    long start, end; 
    ifstream ifile; 
    ifile.open("test.txt", ios::in | ios::binary); 
    start = ifile.tellg(); 
    ifile.seekg(0, ios::end);
    end = ifile.tellg(); 
    ifile.close(); 
    cout << (end - start) << " bytes.\n"; //文件字节大小 
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/401276.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【六祎 - 前端】npm是什么?npm是网站、注册表、命令行工具组成;windows安装nvm;使用nvm安装npm;

nvm管理并安装npmnpm中文文档npm是什么&#xff1f;npm 由三个独立的部分组成&#xff1a;快速入门命令行npm用法npm配置查找包&#xff08;package&#xff09;windows安装nvm使用nvm安装npmps:切换版本下载npm之后的一些配置&#xff08;Optional)npm中文文档 →_→点我查看…

Java的stream流

Java 8中引入的新特性&#xff0c;stream流通过与Lambda表达式结合&#xff0c;采用函数式编程&#xff0c;简化数组、集合操作&#xff0c;提高效率。 我们操作一个集合&#xff0c;就把他看作一个流&#xff0c;整个流依次执行&#xff0c;&#xff08;可以类比为一个管道&a…

企业官网怎么做?

企业官网是企业展示形象和吸引潜在客户的重要渠道之一&#xff0c;因此如何打造一款优秀的企业官网显得尤为重要。本文将从策划、设计、开发和上线等方面&#xff0c;为您介绍企业官网的制作步骤。 一、策划 1.明确目标 企业官网的制作需要明确目标&#xff0c;即确定官网的主…

4. SSM 整合

文章目录1. 引言2. 创建工程3. SSM 整合2. 统一结果封装3. 统一异常处理3.1 异常处理器3.2 项目异常处理方案3.2.1 异常分类3.2.2 异常解决方案3.2.3 异常解决方案的具体实现4. 前后台协议联调4.1 列表功能4.2 添加功能4.3 修改功能4.4 删除功能5. 拦截器5.1 拦截器概念1. 引言…

mysql数据库之innodb存储引擎架构之内存架构

一、逻辑存储结构 mysql5.5版本开始&#xff0c;默认使用innodb存储引擎&#xff0c;它擅长事务处理&#xff0c;具有崩溃恢复特性&#xff0c;在日常开发中使用非常广泛。 架构图&#xff08;左侧为内存架构&#xff0c;右侧为磁盘架构&#xff09; 二、 内存架构。 1、缓冲…

SpringBoot使用Redis实现缓存

目录 实现步骤 1. 在 pom.xml 配置文件中添加如下依赖 2. 在 application.properties 中添加如下配置 3. 新建 RedisConfig.class&#xff0c;继承 CachingConfigurerSupport&#xff0c;添加如下方法 4. 新建 RedisService.class 添加如下方法 注意&#xff1a;cacheKey…

看完书上的栈不过瘾,为什么不动手试试呢?

一.栈的基本概念1.栈的定义栈&#xff08;Stack&#xff09;&#xff1a;是只允许在一端进行插入或删除的线性表。首先栈是一种线性表&#xff0c;但限定这种线性表只能在某一端进行插入和删除操作。其中注意几点&#xff1a;栈顶&#xff08;Top&#xff09;&#xff1a;线性表…

2023年新三板产品及服务研究报告

第一章 概述 全国中小企业股份转让系统&#xff08;英语&#xff1a;National Equities Exchange and Quotations&#xff0c;缩写NEEQ&#xff09;&#xff0c;简称股转系统&#xff0c;是第三家全国性证券交易场所&#xff0c;因挂牌企业均为高科技企业而不同于原转让系统内…

软件测试12

一 Linux命令的共通知识点 1.通配符的使用 通配符&#xff1a;又叫文件名替换符号&#xff0c;符号具备特殊含义&#xff0c;例如&#xff1a;文件名&#xff1a;test&#xff0c;通配符可以写成???或者* *&#xff1a;代表可以匹配任意长度的文件名&#xff08;all所有&am…

xxl-job registry fail

解决方法&#xff1a; 1、检查nacos是否正确&#xff0c;一定要注意格式&#xff0c;一般都是addersses的地址问题&#xff0c;一定的要加/不然找不到&#xff0c;本机就不要使用ip了&#xff0c;用localhost。 xxl: job: admin: addresses: http://localhost:8080/xxl-job-ad…

【java】 java开发中 常遇到的各种难点 思路方案

文章目录逻辑删除如何建立唯一索引唯一索引失效问题加密字段模糊查询问题maven依赖冲突问题&#xff08;jar包版本冲突问题&#xff09;sql in条件查询时 将结果按照传入顺序排序作为一个开发人员 总会遇到各种难题 本文列举博主 遇见/想到 的例子 &#xff0c;也希望同学们可以…

【LVGL移植】STM32F1基于STM32CubeMX配置硬件SPI驱动1.8寸TFT ST7735S跑LVGL图形demo

【LVGL移植】STM32F1基于STM32CubeMX配置硬件SPI驱动1.8寸TFT ST7735S屏幕跑LVGL图形demo&#x1f3ac;运行LVGL 按键组件demo ✨基于STM32CubeMX配置工程是因为方便移植&#xff0c;只要是STM32芯片&#xff0c;拿到我的这个工程源码就可以根据自己的stm32芯片&#xff0c;自…

操作系统复试

2017软学 给出操作系统的定义&#xff0c;分别从资源管理&#xff0c;任务调度&#xff0c;用户接口等三个方面论述操作系统的职能 操作系统是位于硬件层之上、所有其他系统软件层之下的一个系统软件&#xff0c;使得管理系统中的各种软件和硬件资源得以充分利用&#xff0c;方…

MATLAB——求连续系统的响应

题目&#xff1a; 已知RC一阶高通电路图的系统函数H(s)为 H(s)UR(S)U(S)RRR1SCsRCsRC1H(s)\frac {UR(S)}{U(S)}R\frac {R}{R\frac {1}{SC}}\frac {sRC}{sRC1}H(s)U(S)UR(S)​RRSC1​R​sRC1sRC​ 其中&#xff1a;R200Ω &#xff0c;C0.47μF 。求其幅度频率响应与相位频率响应…

公网NAT网关与VPC NAT网关介绍与实践

NAT网关介绍 NAT网关是一种网络地址转换服务&#xff0c;提供NAT代理&#xff08;SNAT和DNAT&#xff09;能力。 公有云NAT分为公网NAT网关和VPC NAT网关。 1&#xff09;公网NAT网关&#xff1a;提供公网地址转换服务。 2&#xff09;VPC NAT网关&#xff1a;提供私网地址转换…

商品获价API调用说明:获取商品历史价格信息 代码分享

接口名称&#xff1a;item_history_price公共参数名称类型必须描述keyString是调用key&#xff08;获取测试key&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_search_shop等]cacheString…

Linux磁盘空间占满了

Linux服务器没有安装很多东西&#xff0c;但是硬盘空间爆满了。。。 df -h 查看硬盘空间&#xff0c;发现使用了99%。 刚开始以为是日志文件的占用的&#xff0c;删除了linux日志文件&#xff0c;发现作用不大&#xff0c;只多了几G。 不妨试试下面的命令 lsof L1 发现了有个…

SQL技能 - 窗口函数

SQL技能 - 窗口函数1. 排序函数1.1. 不分组排序1.2. 分组排序2. 聚合函数实现滑动窗口计算2.1. 常用聚合函数2.2. 滑动行范围的常用表达2.3. 示例3. lag、lead函数求增长率&#xff08;同比、环比&#xff09;窗口函数表达式&#xff1a; function(arg) OVER ([PARTITION BY ex…

K8s kubectl 高效使用技巧,搞定批处理!

1.kubectl用法详解 1. kubectl语法 kubectl [command] [Type] [NAME] [flags] command: 子命令&#xff0c;用于操作kubernetes集群资源对象的命令&#xff0c;例如&#xff1a;create, delete, describe, get, apply等等 TYPE: 资源对象的类型&#xff0c;区分大小写&#…

可视化组件届的仙女‖蝴蝶结图、玫瑰环图、小提琴图

在上一篇内容中为大家介绍了几个堪称可视化组件届吴彦祖的高级可视化图表。既然帅哥有了&#xff0c;怎么能少得了美女呢&#xff1f;今天就为大家介绍几个可视化组件届的“美女姐姐”&#xff0c;说一句是组件届的刘亦菲不为过。蝴蝶结图蝴蝶结图因其形似蝴蝶结而得名&#xf…