当前位置: 首页 > news >正文

C++ 之 【C++的IO流】

目录

1. C++IO流

1.1 C++标准IO流

自定义类型隐式转换为内置类型

1.2 C++文件IO流

打开文件

文本文件的读写

二进制文件的读写

完整示例


1. C++IO流

C++系统实现了一个庞大的类库,其中ios为基类,其他类都是直接或间接派生自ios类

1.1 C++标准IO流

C++标准库提供了4个全局流对象cin、cout、cerr、clog

使用cout进行标准输出,即数据从内存流向控制台(显示器)

使用cin进行标准输入,即数据通过键盘输入到程序中,

同时C++标准库还提供了cerr用来进行标准错误的输出,以及clog进行日志的输出

从上图可以看出,cout、cerr、clog是ostream类的三个不同的对象,

因此这三个对象现在基本没有区别,只是应用场景不同

在使用时候必须要包含文件并引入std标准命名空间

注意:

1. cin为缓冲流。键盘输入的数据保存在缓冲区中,当要提取时,是从缓冲区中拿。如果一次输入过多,会留在那儿慢慢用,如果输入错了,必须在回车之前修改,如果回车键按下就无法挽回了。只有把输入缓冲区中的数据取完后,才要求输入新的数据。

2. 输入的数据类型必须与要提取的数据类型一致,否则出错。出错只是在流的状态字state中对应位置位(置1),程序继续。

3. 空格和回车都可以作为数据之间的分格符,所以多个数据可以在一行输入,也可以分行输

入。但如果是字符型和字符串,则空格(ASCII码为32)无法用cin输入,字符串中也不能有

空格。回车符也无法读入

4. cin和cout可以直接输入和输出内置类型数据,

原因:标准库已经将所有内置类型的输入和输出全部重载了

5. 对于自定义类型,如果要支持cin和cout的标准输入输出,需要对>>、<<进行重载。

6. 在线OJ中的输入和输出:

对于IO类型的算法,一般都需要循环输入

输出:严格按照题目的要求进行,多一个少一个空格都不行

连续输入时,vs系列编译器下在输入ctrl+Z时结束

// 单个元素循环输入
while(cin>>a){// ...}// 多个元素循环输入
while(c>>a>>b>>c){// ...}// 整行接收
while(cin>>str){// ...}

7. istream类型对象转换为逻辑条件判断值

istream& operator>> (int& val);explicit operator bool() const;

实际上我们看到使用while(cin>>i)去流中提取对象数据时,调用的是operator>>,返回值是 istream类型的对象,那么这里可以做逻辑条件值,源自于istream的对象又调用了operator bool,operator bool调用时如果接收流失败,或者有结束标志,则返回false

cin.operator >>(i).operator bool();
  • 自定义类型隐式转换为内置类型

class A
{
public:A(int a):_a(a){ }operator int(){return _a;}private:int _a;
};int main()
{//自定义类型<-内置类型A aa1 = 1;//内置类型<-自定义类型int a = aa1;cout << a << endl;return 0;
}

成员函数 operator int 使得自定义类型能够隐式转换为内置类型 int

explicit 修饰构造函数,禁止隐式类型转换,仍可通过显式调用构造(A aa1(1);)

explicit 修饰operator int ,禁止隐式转换(必须 int x = static_cast<int>(a))

1.2 C++文件IO流

C++根据文件内容的数据格式分为二进制文件和文本文件

采用文件流对象操作文件的一般步骤:

1. 定义一个文件流对象

  • ifstream ifile(只输入用)
  • ofstream ofile(只输出用)
  • fstream iofile(既输入又输出用)

2. 使用文件流对象的成员函数打开一个磁盘文件,使得文件流对象和磁盘文件之间建立联系

3. 使用提取和插入运算符对文件进行读写操作,或使用成员函数进行读写

4. 关闭文件

  • 打开文件

使用ifstream、ofstream和fstream类中的成员函数open打开文件

◼open函数原型如下所示

void open(constunsigned char* filename,intmode, intaccess=filebuf::openprot);⚫

第一个参数用来传递文件名;

第二个参数mode 的值决定文件的打开方式;

第三个参数决定文件的保护方式,用户通常只使用缺省值。

打开方式是已经在ios类中定义了的枚举常量,常用的有以下几种:

ios::in打开一个文件用于输入(读)操作。

ios::out打开一个文件用于输出(写)操作。

ios::ate打开一个已有的文件,文件指针指向文件尾。

ios::app以输出方式打开文件,写入的数据追加在文件末尾。

ios::trunc打开一个文件。如果文件已存在,则删除其中全部数据;如果文件不存在,则建立新文件。如果已指定了ios::out,而未指定ios::app、ios::ate、ios::in,则同时默认此方式。ios::nocreate打开一个已有的文件,如果文件不存在,则打开文件失败(即不创建一个新文件)。

ios::noreplace如果文件不存在,则建立新文件;如果文件存在,则打开失败。noreplace是不更新原有文件的意思。

ios::binary 指定文件以二进制方式打开,而不是缺省说明的文本方式

◼用构造函数打开文件的格式有以下几种:

⚫ifstream对象名("文件名")

⚫ofstream对象名("文件名")

⚫fstream对象名("文件名",打开方式)

ofstreamfout(“mytest.txt”);

上述语句相当于:

ofstreamfout;        fout.open("mytest.txt");

  • 文本文件的读写

对文本文件的读写操作可以使用以下两种方法:

⚫用流输出运算符“<<”和流输入运算符“>>”输入输出标准类型的数据。

⚫用文件流的put 、get 和getline等成员函数进行字符的输入输出

std::ofstream outFile("data.txt");
if (outFile) {// 写入各种类型数据outFile << "字符串" << " " << 123 << " " << 45.67 << std::endl;// 写入单个字符outFile.put('A');
}std::ifstream inFile("data.txt");
if (inFile) {// 方法1:使用 >> 运算符std::string str;int num;double d;inFile >> str >> num >> d;// 方法2:逐行读取std::string line;while (std::getline(inFile, line)) {std::cout << line << std::endl;}// 方法3:逐个字符读取char ch;while (inFile.get(ch)) {std::cout << ch;}
  • 二进制文件的读写

二进制文件读写主要用istream类的成员函数read和ostream类的成员函数write来实现的。

这两个函数的原型如下所示。

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

⚫其中,read() 是流类istream中的成员函数,

其功能为:从相应的流中读取len个字节,并把它们放入指针buffer 所指向的缓冲区中。

⚫由于参数buffer 的类型为char *。因此当输入其他类型数据时,必须进行类型转换。例如:intarrryi[]={100,200,300};        read((char *)&arrayi[0],sizeof(arrayi));

std::ofstream outFile("data.txt");
if (outFile) {   // 写入字符数组const char* text = "C-style string";outFile.write(text, strlen(text));
}std::ifstream inFile("data.txt");
if (inFile) {    //读取指定字节数(二进制模式)char buffer[100];inFile.read(buffer, sizeof(buffer));
}

完整示例

struct ServerInfo
{char _address[32];int _port;Date _date;
};
struct ConfigManager
{
public:ConfigManager(const char* filename):_filename(filename){}void WriteBin(const ServerInfo& info){ofstream ofs(_filename, ios_base::out | ios_base::binary);ofs.write((const char*)&info, sizeof(info));}void ReadBin(ServerInfo& info){ifstream ifs(_filename, ios_base::in | ios_base::binary);ifs.read((char*)&info, sizeof(info));}// C++文件流的优势就是可以对内置类型和自定义类型,都使用// 一样的方式,去流插入和流提取数据// 当然这里自定义类型Date需要重载>> 和 <<// istream& operator >> (istream& in, Date& d)// ostream& operator << (ostream& out, const Date& d)void WriteText(const ServerInfo& info){ofstream ofs(_filename);ofs << info._address << " " << info._port << " " << info._date;}void ReadText(ServerInfo& info){ifstream ifs(_filename);ifs >> info._address >> info._port >> info._date;}
private:string _filename; // 配置文件
};
int main()
{ServerInfo winfo = { "192.0.0.1", 80, { 2022, 4, 10 } };// 二进制读写ConfigManager cf_bin("test.bin");cf_bin.WriteBin(winfo);ServerInfo rbinfo;cf_bin.ReadBin(rbinfo);cout << rbinfo._address << "  " << rbinfo._port << "  "<< rbinfo._date << endl;// 文本读写ConfigManager cf_text("test.text");cf_text.WriteText(winfo);ServerInfo rtinfo;cf_text.ReadText(rtinfo);cout << rtinfo._address << "  " << rtinfo._port << "  " <<rtinfo._date << endl;return 0;
}
http://www.dtcms.com/a/394328.html

相关文章:

  • truffle学习笔记
  • 现代循环神经网络
  • vlc播放NV12原始视频数据
  • ThinkPHP8学习篇(七):数据库(三)
  • 链家租房数据爬虫与可视化项目 Python Scrapy+Django+Vue 租房数据分析可视化 机器学习 预测算法 聚类算法✅
  • MQTT协议知识点总结
  • C++ 类和对象·其一
  • TypeScript里的类型声明文件
  • 【LeetCode - 每日1题】设计电影租借系统
  • Java进阶教程,全面剖析Java多线程编程,线程安全,笔记12
  • DCC-GARCH模型与代码实现
  • 实验3掌握 Java 如何使用修饰符,方法中参数的传递,类的继承性以及类的多态性
  • 【本地持久化】功能-总结
  • 深入浅出现代FPU浮点乘法器设计
  • LinkedHashMap 访问顺序模式
  • 破解K个最近点问题的深度思考与通用解法
  • 链式结构的特性
  • 报表1-创建sql函数get_children_all
  • 9月20日 周六 农历七月廿九 哪些属相需要谨慎与调整?
  • godot实现tileMap地图
  • 【Unity+VSCode】NuGet包导入
  • QEMU虚拟机设置网卡模式为桥接,用xshell远程连接
  • Week 17: 深度学习补遗:Boosting和量子逻辑门
  • 【论文速递】2025年第13周(Mar-23-29)(Robotics/Embodied AI/LLM)
  • Webpack进阶配置
  • 【LeetCode 每日一题】3227. 字符串元音游戏
  • 【图像算法 - 26】使用 YOLOv12 实现路面坑洞智能识别:构建更安全的智慧交通系统
  • 009 Rust函数
  • IT疑难杂症诊疗室
  • 视频播放器下载推荐,PotPlayer‌,KMPlayer,MPC-HC,GOM Player‌VLC media player,MPV,