【STL】iostream 编程:输入/输出替换选项


本文介绍一下输入/输出替换选项的几种方法。


目录

  • [1 输入输出的可选方案](#1 输入输出的可选方案)
  • [2 Windows 下流对象的兼容性问题](#2 Windows 下流对象的兼容性问题)
  • [3 方案选型列表](#3 方案选型列表)
  • [4 总结](#4 总结)

1 输入输出的可选方案

微软 C++编译器提供了多种 I/O 编程方案:

  1. C运行时库无缓冲直接 I/O
    • 头文件 <io.h>,API:_open,_read,_write,_close;
    • 没有缓冲区,调用一次就直接调用操作系统内核接口;
    • 适合底层硬件读写、二进制大块数据;
    • 优点:控制粒度极强;
    • 缺点:频繁调用会产生大量系统调用,性能差;
  2. ANSI C标准库流式 I/O (stdio)
    • FILE*、fopen、fprintf、fread、fwrite;
    • 自带用户层缓冲区,减少系统调用;
    • 支持格式化文本输出;
    • 纯 C 过程式写法,没有面向对象封装,没有类型安全;
  3. 控制台与串口的硬件直写 I/O
    • 直接调用 Windows 控制台 API、串口API,绕过标准库;
    • 多用于工控程序、串口通信、控制台高级颜色与光标控制;
  4. MFC 微软基础类库
    • CFile、CStdioFile
    • 封装了文件读写,自带窗口消息环境,只适用于 MFC 项目;
  5. C++标准库 iostream(cin / cout / ifstream / ostringstream)
    • 带缓冲的格式化文本读写(日常日志、文本文件);
    • 不依赖 MFC 时,作为纯 C++ 的二进制读写方案;
    • 面向对象封装,运算符重载,支持自定义对象直接输出;
      iostream 类适合带缓冲的格式化文本读写。如果想要纯 C++接口且不使用 MFC,它也可以处理无缓冲 I/O 与二进制文件读写。作为面向对象方案,它可以完全替代 C语言运行时 I/O 函数。
      在 Windows 平台使用 iostream 时:字符串流与文件流不受任何限制。但字符控制台流 cin、cout、cerr、clog 和 Windows 图形界面程序不兼容。开发者也可以派生自定义流类,直接对接 Windows 系统环境。

2 Windows 下流对象的兼容性问题

  1. 文件流 ifstream / ofstream、字符串流 stringstream
    • 完全独立,只操作内存与磁盘文件,不依赖控制台窗口,控制台程序、GUI窗口程序都能正常使用,没有任何限制
  2. 全局控制台流:cin、cout、cerr、clog
    • 这几个对象默认绑定控制台黑窗口;
    • Windows窗口 GUI项目(Win32/MFC):程序本身没有控制台窗口,此时调用 cout 输出,内容无处打印,会出现输出失效、卡死、输出丢失问题

3 方案选型列表

方案 特点 适用项目
原生无缓冲 I/O 底层、无缓冲 硬件读写、大块二进制
C stdio 简洁、带缓冲、格式化 跨平台 C 程序
iostream 面向对象、类型安全、支持自定义对象 纯 C++ 项目,不使用 MFC
MFC CFile 集成窗口框架 MFC 窗口程序
Windows 原生 API 深度控制系统设备 GUI、串口、控制台高级控制

4 总结

  1. MSVC 一共提供5套 IO 体系,覆盖从底层内核调用到高层面向对象封装;
  2. iostream 是带缓冲的面向对象 IO 库,既能处理文本也能处理二进制,用来代替 C stdio;
  3. Windows GUI 程序不能直接使用 cout/cin,但文件流与内存字符串流不受影响;
  4. 想要把流输出写到窗口控件,可以继承流缓冲区,自定义实现 Windows 版本的流;