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

c++IO类

概述

c++不直接处理输入输出,而是通过定义在标准类库中的类来处理IO。这些类支持从设备读取数据,向设备写入数据的IO操作,设备可以是文件、控制台窗口等。还可以从内存IO。


IO类

  • iostream:
    1. istream,wistream
    2. ostream,wostream
    3. iostream,wiostream
  • ftream:
    1. iftream, wifstream
    2. oftream, wofstream
    3. fstream, wfstream
  • sstream:
    1. istringstream, wistream
    2. ostringstream, wostringstream
    3. stringstream, wstringstream

前缀w是处理宽字符的版本。

标准库使我们能够忽略不同流之间的差异,这是通过继承机制实现的。iftreamistringstream都继承自istream对象。类似的ofstreamostringstream都继承自ostream


IO对象无拷贝或赋值

在之前的博文中说过,IO对象是不可以拷贝或赋值的。所以我们不能将形参或返回值的类型设置为流类型。进行IO的函数通常以引用的方式传递和返回流。读写IO通常会改变对象的状态,所以传递和返回的引用通常不是const的。

ofstream out1, out2;
out1 = out2; //错误,不能对流对象赋值
oftream print(ofstream); //错误,不能初始化ofstream参数
out2 = print(out2); //错误,不能拷贝流对象

条件状态

IO操作可能会发生错误,一些错误是可以恢复的。下表列出了IO类定义的一些函数和标志,可以帮助我们访问和操纵流的条件状态

流状态标志位

状态标志值(二进制)说明
goodbit000流状态正常,没有错误
eofbit001到达文件末尾(End Of File)
failbit010发生可恢复错误(如类型不匹配)
badbit100发生严重错误(如流损坏)

流状态查询函数

函数返回值说明
s.eof()bool如果设置了eofbit则返回true
s.fail()bool如果设置了failbitbadbit则返回true
s.bad()bool如果设置了badbit则返回true
s.good()bool如果流状态正常(所有错误位未设置)则返回true
s.rdstate()iostate返回流的当前状态值

流状态操作函数

函数参数说明
s.clear()重置所有错误标志,将流状态设置为goodbit
s.clear(flags)iostate将流状态设置为指定值
s.setstate(flags)iostate添加指定的状态标志

一个流一旦发生错误,其上后续的IO操纵都会失败。只有当一个流处于无错误的状态时,我们才可以从中读取数据,或向它写入数据。我们应该在使用一个流之前检查它是否处于良好状态。

while (cin >> word)//ok:读操作成功

我们也可以查询流的状态。IO库中定义了一个与机器无关的类型iostate,它提供了表达流状态的完整功能。使用goodfailbad等函数确定流的错误状态。

通过使用rdstatesetstateclear来管理条件状态。

接下来给出一个示例,用于从一个istream对象中读取数据,并将数据打印在控制台中:

#include <iostream>
#include <string>std::istream& readAndPrint(std::istream& is) {std::string word;while (is >> word) {  // 读取直到文件结束std::cout << word << " ";  // 打印读取的内容}std::cout << std::endl;is.clear();  // 复位流状态return is;
}

管理输出缓冲

每个输出流都管理一个缓冲区,用来保存程序读写的数据。考虑如下代码:

os << "please enter a value: ";

字符串可能不会立即被显示出来,而是被操作系统保存在缓冲区中,随后再打印。有了缓冲区机制,操作系统就可以把多个输出操作合并为单一的系统极写操作,这将极大地提升程序地性能。

缓冲区刷新指的是数据真正地写入到设备或文件中,导致缓冲区刷新地原因有很多:

  • 程序正常结束,main中地return语句被执行,导致缓冲区刷新。
  • 缓冲区满
  • 使用endl显式刷新缓冲区
  • 使用unitbuf设置流的内部状态,以此来清空缓冲区。
  • 一个输出流可能关联到另一个流。当读写被关联的流时,关联到的流的缓冲区会被刷新。

示例代码如下所示:

#include <iostream>
#include <fstream>
#include <unistd.h>  // 用于 sleep 函数// 1. 程序正常结束导致缓冲区刷新
void normalTermination() {std::cout << "\n1. 程序正常结束刷新示例:\n";std::cout << "这条消息会在程序结束时自动刷新";// 无显式刷新,依靠main函数return刷新
}// 2. 缓冲区满导致自动刷新
void bufferFull() {std::cout << "\n2. 缓冲区满自动刷新示例:\n";// 通常缓冲区大小约为4KB,这里用循环填满for (int i = 0; i < 1000; ++i) {std::cout << "填充缓冲区数据 " << i << " ";}std::cout << "\n缓冲区已满并自动刷新\n";
}// 3. 使用endl显式刷新
void explicitFlush() {std::cout << "\n3. 使用endl显式刷新示例:\n";std::cout << "这条消息会立即显示" << std::endl;std::cout << "下一条消息" << std::endl;
}// 4. 使用unitbuf设置流状态
void unitbufExample() {std::cout << "\n4. unitbuf设置示例:\n";std::cout << std::unitbuf;  // 开启每次操作后自动刷新std::cout << "unitbuf模式 - 每次输出后自动刷新";sleep(1);std::cout << " 即使没有换行也会刷新";std::cout << std::nounitbuf;  // 关闭自动刷新std::cout << "\n恢复普通模式\n";
}// 5. 关联流导致的刷新
void tiedStreams() {std::cout << "\n5. 关联流刷新示例:\n";std::ofstream logfile("log.txt");// 将cout与logfile关联std::cout.tie(&logfile);std::cout << "向cout写入会刷新logfile: ";logfile << "这条消息会立即写入文件\n";// 请求输入也会刷新关联的coutstd::cout << "请输入一个数字: ";int num;std::cin >> num;std::cout << "你输入了: " << num << std::endl;// 恢复默认关联std::cout.tie(nullptr);
}int main() {normalTermination();bufferFull();explicitFlush();unitbufExample();tiedStreams();// 程序结束时会自动刷新所有缓冲区return 0;
}
http://www.xdnf.cn/news/1067113.html

相关文章:

  • HTML语义化标签
  • ubuntu安装postman教程并中文汉化详细教程
  • 互联网大数据求职面试:从Zookeeper到Flink的技术探讨
  • Gateway路径匹配规则易错点
  • 自回归(AR)与掩码(MLM)的核心区别:续写还是补全?
  • VitePress搭建静态博客
  • 【机器人-深度估计】双目深度估计原理解析
  • 【格与代数系统】示例2
  • 黑马程序员苍穹外卖DAY1
  • 【AI News | 20250623】每日AI进展
  • 基于openfeign拦截器RequestInterceptor实现的微服务之间的夹带转发
  • 支持java8的kafka版本
  • Python csv 模块
  • Spring MVC极简入门:从@Request到Postman的全链路开发
  • python中学物理实验模拟:平抛运动和抛物运动
  • 苹果芯片macOS安装版Homebrew(亲测) ,一键安装node、python、vscode等,比绿色软件还干净、无污染
  • 触摸屏(典型 I2C + Input 子系统设备)从设备树解析到触摸事件上报
  • 深入浅出Node.js后端开发
  • Python基础之函数
  • Python基础(​​FAISS​和​​Chroma​)
  • Redis哨兵模式深度解析与实战部署
  • 如何实现财务自由
  • 操作系统 第九章 部分
  • 飞往大厂梦之算法提升-7
  • 第一节 布局与盒模型-Flex与Grid布局对比
  • Java的SpringAI+Deepseek大模型实战【二】
  • Vue实现选中多张图片一起拖拽功能
  • 华为HN8145V光猫改华为蓝色公版界面,三网通用,xgpon公版光猫
  • [NocoDB] 在局域网中调整Float类型显示精度的部署经验
  • 《哈希表》K倍区间(解题报告)