Linux C\C++方式下的文件I/O编程

server/2025/1/21 22:02:00/

【图书推荐】《Linux C与C++一线开发实践(第2版)》_linux c与c++一线开发实践pdf-CSDN博客

《Linux C与C++一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 

LinuxC\C++编程技术_夏天又到了的博客-CSDN博客

4.9.1  流的概念

在C++语言中,数据的输入和输出包括对标准输入设备(键盘)和标准输出设备(显示器)、外存磁盘上的文件以及内存中指定的字符串存储空间(当然可用该空间存储任何信息)进行输入输出。对标准输入设备和标准输出设备的输入输出简称为标准I/O,对外存磁盘上的文件的输入输出简称为文件I/O,对内存中指定的字符串存储空间的输入输出简称为(字符)串I/O。

“流”就是“流动”,是物质从一处向另一处流动的过程。C++流是指信息从外部输入设备(如键盘和磁盘)向计算机内部(即内存)输入和从内存向外部输出设备(如显示器和磁盘)输出的过程,这种输入输出过程被形象地比喻为“流”。为了实现信息的内外流动,C++系统定义了I/O类库,其中的每一个类都称作相应的流或流类,用以完成某一方面的功能。一个流类定义的对象也时常被称为流。例如根据文件流类fstream定义的一个对象fio可称作fio流或fio文件流,用它可以同磁盘上的一个文件相联系,实现对该文件的输入和输出,fio就等同于与之相联系的文件。

因为C++兼容C,所以C中的输入输出函数依然可以在C++中使用,但是很显然,直接把C的那套输入输出搬到C++中肯定无法满足C++的需求,更重要的一点是,C中的输入输出有类型要求,只支持基本类型,因此C++设计了易于使用的并且多种输入输出流接口统一的I/O类库,并且支持多种格式化操作,还可以自定义格式化操作。总体来说,C++中有3种输入输出流。

(1)标准I/O流:内存与标准输入输出设备之间信息的传递。

(2)文件I/O流:内存与外部文件之间信息的传递。

(3)字符串I/O流:内存变量与表示字符串流的字符数组之间信息的传递。

C++引入I/O流,将这3种输入输出流接口统一起来,使用符号“>>”读取数据的时候,不用去管是从何处读取数据,使用符号“<<”写数据的时候,也不需要管是写到哪里去。

4.9.2  流的类库

C++语言系统为实现数据的输入和输出定义了一个庞大的类库,其中ios为根基类,其余都是它的直接或间接派生类,它直接派生4个类:输入流类istream、输出流类ostream、文件流基类fstreambase和字符串流基类strstreambase。C++系统中的I/O类库的所有类被包含在iostream、fstream和strstream这3个系统头文件中。我们可以用图4-4来表示各个类的继承关系。

图4-4

头文件<fstream>提供了3个文件流类:ifstream、ofstream和fstream。

值得注意的是,要在C++中进行文件处理,必须在C++源码文件中包含头文件<fstream>。此外,在C++新标准中,头文件都把.h去掉了,如#include<fstream.h>现在要用:

#include<fstream> using namespace std; 

同时要把标准命名空间加上。但是fstream.h和fstream并不是完全等价的。在旧头文件里的fstream.h,如果使用ifstream file的默认参数声明一个输入文件流,当这个要读的file文件不存在时,会自动创建一个空文件,从而给判断文件是否存在造成了很多麻烦。如果使用新标准fstream,就不会创建空文件,从而可以用while(!file)来判断文件是否存在,通过返回数值来指导程序运行。

类似地,头文件ostream.h与iostream也是不同的。iostream.h在旧的C++标准中使用,新标准中用iostream,还要引用命名空间std。iostream.h慢慢地不再使用了,比如微软的VC6可以使用iostream.h,VS 2008已经不能使用iostream.h了。好像不习惯将没有.h 结尾的文件称为头文件,但与时俱进吧,头文件不一定要.h。

4.9.3  打开文件

在从文件读取信息或者向文件写入信息之前,必须先打开文件。ofstream和fstream对象都可以用来打开文件进行写操作,如果只需要打开文件进行读操作,就使用ifstream对象。被打开的文件在程序中由一个流对象来表示(这些类的一个实例),而对这个流对象所做的任何输入输出操作实际上就是对该文件所做的操作。要通过一个流对象打开一个文件,需要使用它的成员函数open()。open()函数是fstream、ifstream和ofstream对象的一个成员,该函数声明如下:

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

其中,第一参数指定要打开的文件的名称和位置,第二个参数定义文件被打开的模式。文件打开模式如表4-3所示。

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

ofstream outfile;outfile.open("file.dat", ios::out | ios::trunc );

类似地,如果想要打开一个文件用于读写,可以使用下面的代码:

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

又比如,如果想要以二进制方式打开文件example.bin来写入一些数据,可以这样写:

ofstream file;file.open ("example.bin", ios::out | ios::app | ios::binary);

ofstream、ifstream和fstream类的成员函数open都包含一个默认打开文件的方式,这3个类的默认方式各不相同,如表4-4所示。

只有在函数被调用且没有声明方式参数的情况下,默认值才会被采用。如果函数被调用时声明了任何参数,默认值将被完全改写,而不会与调用参数组合。

由于对类ofstream、ifstream和fstream的对象所进行的第一个操作通常都是打开文件,因此这些类都有一个构造函数可以直接调用open函数,并拥有同样的参数。这样,我们就可以通过以下方式进行与上面同样的定义对象和打开文件的操作:

ofstream file ("example.bin", ios::out | ios::app | ios::binary); // 定义对象的同时直接打开文件

两种打开文件的方式都是正确的。

另外,我们可以通过调用成员函数is_open(),来检查一个文件是否已经被顺利地打开了:

bool is_open();

该函数返回一个布尔值,值为真(true)代表文件已经被顺利打开,值为假(false)则相反。

4.9.4  关闭文件

当文件读写操作完成之后,我们必须将文件关闭以使文件重新变为可访问的。关闭文件需要调用成员函数close(),它负责将缓存中的数据释放出来并关闭文件。close()函数是fstream、ifstream和ofstream对象的一个成员函数,声明如下:

void close();

这个函数一旦被调用,原先的流对象就可以被用来打开其他的文件了,这个文件也就可以重新被其他的进程访问了。为防止流对象被销毁时还联系着打开的文件,析构函数将会自动调用关闭函数close()。

4.9.5  写入文件

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

4.9.6  读取文件

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

下面来看一个例子,以读写模式打开一个文件。在向文件afile.dat写入用户输入的信息之后,程序从文件读取信息,并将其输出到屏幕上。

【例4.13】用C++流的方式读写文件

(1)打开Visual Studio Code,新建文本文件test.cpp,输入代码如下:

#include <fstream>
#include <iostream>
using namespace std;int main ()
{char data[100];// 以写模式打开文件ofstream outfile;outfile.open("afile.dat");cout << "Writing to the file" << endl;cout << "Enter your name: "; cin.getline(data, 100);// 向文件写入用户输入的数据outfile << data << endl;cout << "Enter your age: "; cin >> data;cin.ignore();// 再次向文件写入用户输入的数据outfile << data << endl;// 关闭打开的文件outfile.close();// 以读模式打开文件ifstream infile; infile.open("afile.dat"); cout << "Reading from the file" << endl; infile >> data; // 在屏幕上写入数据cout << data << endl;// 再次从文件读取数据,并显示它infile >> data; cout << data << endl; // 关闭打开的文件infile.close();return 0;
}

(2)上传test.cpp到Linux,在终端下输入命令g++ -o test test.cpp,然后运行test,结果如下:

# g++ -o test test.cpp
# ./test
Writing to the file
Enter your name: zww
Enter your age: 61
Reading from the file
zww
61

可以看到在同目录下生成了一个文件afile.dat,查看里面的内容可得:

# cat afile.dat
zww
61

上面的例子中使用了cin对象的附加函数,比如getline()函数从外部读取一行,ignore()函数会忽略掉之前读语句留下的多余字符。


http://www.ppmy.cn/server/160289.html

相关文章

Node.js卸载超详细步骤(附图文讲解)

Node.js卸载超详细步骤 1、通过控制面板删除node版本2、删除node的安装目录3、查找.npmrc文件是否存在&#xff0c;有就删除。4、查看以下文件是否存在&#xff0c;有就删除5、打开系统设置&#xff0c;检查系统环境变量&#xff0c;将node相关的配置都删掉6、查看是否删除成功…

产品经理面试题总结2025【其一】

一、产品理解与定位 1、你如何理解产品经理这个角色&#xff1f; 作为一名互联网产品经理&#xff0c;我理解这个角色的核心在于成为产品愿景的制定者和执行的推动者。具体来说&#xff0c;产品经理是连接市场、用户和技术团队之间的桥梁&#xff0c;负责理解市场需求、用户痛…

自动驾驶3D目标检测综述(八)

在介绍完前九章的内容后&#xff0c;咱们已经基本完成了综述主题内容的解读。剩下只有第十章分析和展望以及第十一章总结的部分。本篇为自动驾驶3D目标检测综述的第八篇也将是最后一篇。 目录 1、研究趋势 1.1 数据选择的趋势 1.2 推理时间的趋势 1.3 基于激光雷达方法的趋…

RabbitMQ--延迟队列

&#xff08;一&#xff09;延迟队列 1.概念 延迟队列是一种特殊的队列&#xff0c;消息被发送后&#xff0c;消费者并不会立刻拿到消息&#xff0c;而是等待一段时间后&#xff0c;消费者才可以从这个队列中拿到消息进行消费 2.应用场景 延迟队列的应用场景很多&#xff0c;…

Vue.js 动态设置表格最大高度的实现

概述 在现代 Web 开发中&#xff0c;响应式设计至关重要&#xff0c;尤其是在处理复杂的布局和数据表格时。表格通常会受到多种因素的影响&#xff0c;如分页、合计行或动态内容&#xff0c;这可能导致表格高度的变化。本文将介绍一个基于 Vue.js 的方法 setMaxHeight&#xf…

新能源科技亲民化路径何在?交互式展厅提供新解吗?

在当今科技迅猛发展的时代&#xff0c;全球能源需求持续增长&#xff0c;新能源的崛起既筑起了环保防线&#xff0c;又开启了能源新纪元。然而&#xff0c;新能源技术的复杂性常令非技术背景的公众难以理解和应用。为此&#xff0c;新能源主题交互式展厅应运而生&#xff0c;成…

解密AIGC三大核心算法:GAN、Transformer、Diffusion Models原理与应用

在当今数字化时代&#xff0c;人工智能生成内容&#xff08;AIGC&#xff09;技术正以前所未有的速度改变着我们的生活和工作方式。从创意无限的文本生成&#xff0c;到栩栩如生的图像创作&#xff0c;再到动听的音乐旋律&#xff0c;AIGC的魔力无处不在。而这一切的背后&#…

mysql的测试方案

1. 测试目标与范围 1.1 性能测试目标 MySQL性能测试旨在评估数据库在不同负载条件下的响应速度、吞吐量和资源利用率&#xff0c;确保其能够满足业务需求。 响应时间&#xff1a;衡量查询和事务处理的延迟&#xff0c;目标是将平均响应时间控制在100毫秒以内&#xff0c;95%的…