C++ iostream 输入输出流
2022/5/30 1:22:28
本文主要是介绍C++ iostream 输入输出流,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录- STL 输入输出流:整体框架
- A) 输入、输出流
- 1. 简介
- 2. 格式化输出
- 3. 流操纵算子
- 4.
cout
对象的唯一性
- B) 文件输入、输出流
- 1. 基本使用方法
- 2. 读入常用操作
- C) 字符串输入、输出流
- 1. 简介
- 2. 对象内的 buffer
- 3. 实现类型转换
STL 输入输出流:整体框架
头文件 | 定义在头文件里的类 / 对象 | 补充说明 |
---|---|---|
<istream> |
istream 类、 iostream 类 |
istream 类是所有输入流的基类 |
<ostream> |
ostream 类 |
ostream 类是所有输出流的基类 |
<iostream> |
cin 对象、 cout 对象 |
cin 是 istream 类的对象;cout 是 ostream 类的对象 |
<fstream> |
ifsream 类、 ofstream 类、 fstream 类 |
|
<sstream> |
istringstream 类、 ostringstream 类、 stringstream 类 |
回到顶部
A) 输入、输出流
*** istream
和 ostream
类似,以下以 ostream
展开说明。
1. 简介
-
ostream
= output stream- 是所有输出流的基类
- 类内重载了不同基础数据类型的输出流运算符,如:
int
、char
、bool
... - 优势:统一了输出接口,避免输出混乱
-
STL 中定义了一个
ostream
类的对象:cout
,将数据送到标准输出流以下是自定义实现
ostream
的方法:class ostream { public: ostream& operator<< (int num) { printf("%d", num); return *this; } ostream& operator<< (const char* str) { printf("%s", str); return *this; } ...... // 重载需要输出的类型 } cout; // 定义 ostream 类的对象 int main() { cout << 21 << "happy" ; // 根据输出数据类型,调用不同的输出函数 return 0; }
以下是在自定义类中重载流运算符的方法:
class MyClass { public: friend ostream& operator<< (ostream&, MyClass&); ...... } ostream& operator<< (ostream& output, MyClass& x) { output << ... ; return outpur; }
注意:第二个参数可以是不同形式,不一定是引用,如:
T
、T&
、const T
、const T&
回到顶部
2. 格式化输出
-
常用的格式化输出方式有:
#include <iomanip> cout << fixed << 3 << " " << 3.14 << " " << 3.14159265; /* 将小数的小数点固定为 6 位 输出结果:3 3.140000 3.141593 */ cout << setprecision(3) << 3.1415926 << 0.1054; /* 设置有效数字 输出结果:3.14 0.105 */ cout << fixed << setprecision(2) << 3.1415; /* fixed 和 setprecision 合用,可以设置小数点数位 输出结果:3.14 */ cout << setw(5) << 921; /* 设置输出的宽度,一次只对一个输出有效 默认向右对齐 */ for(int i = 8; i <= 12; ++i) { cout << setw(5) << setfill('*') << i; } /* 设置输出的宽度 + 空白处填满指定字符 输出结果:****8****9***10***11***12 */ cout << scientific << 2018.0 << " " << 0.0001; /* 以科学计数形式输出 输出结果:2.018000e+03 1.000000e-04 */
-
以上的
fixed
、setprecision()
等,包括实现换行的endl
,都是流操纵算子
回到顶部
3. 流操纵算子
-
借助辅助类,设置成员变量的类
-
一些实现方式有在标准中定义,一些没有,不同编译器的实现不同
-
setprecision
实现的示例:class setprecision { private: int precision; public: setprecision(int p): precision(p) {} friend class ostream; } class ostream { private: int precision; public: ostream& operator<< (const setprecision &m) { precision = m.precision; return *this; } } cout; cout << setprecision(2); // setprecision(2) 会构造一个 setprecision 类的对象,作为参数传入输出流的函数
-
endl
实现的示例:class ostream { ...... ostream& endl(ostream& os) { os.put('\n'); // 输出换行符 os.flush(); // 清空缓冲区 return os; } ostream& operator<< (ostream& (*fn)(ostream&)) { return (*fn)(*this); } } // 换行方法1:调用输出流+流操纵算子 cout << endl; // 换行方法2:直接使用endl函数 endl(cout);
清空缓冲区的好处:减少外部读写次数、保证内容正确读写到文件
回到顶部
4. cout
对象的唯一性
-
定义重载流运算符 / 使用
cout
的方式:-
所有重载流运算符都会返回引用
ostream&
-
ostream
类的拷贝构造函数会手动进行删除ostream(const ostream& x) = delete; ostream(ostream&& x);
-
-
原因:
- 减少复制开销
- 只移动不复制,只使用一个全局对象
cout
进行输出 - 多个对象无法同步输出状态
回到顶部
B) 文件输入、输出流
类 | 名 | 功能 | 补充说明 |
---|---|---|---|
ifstream |
文件输入流 | 从文件中读取数据 | 是 istream 的子类在编译期间已经解析完毕 性能较好,取代了 scanf ( scanf 是有写入非法内存的风险) |
ofstream |
文件输出流 | 将数据写入文件中 | 是 ostream 的子类 |
*** ifstream
和 ofstream
类似,以下以 ifstream
进行说明:
回到顶部
1. 基本使用方法
#include <fstream> #include <iostream> using namespace std; int main() { // 打开普通文本文件 ifsream input("filename.txt"); // 以二进制形式打开文件 ifstream input("filename.bin", ifstream::binary); // 确保文件正确打开才进行操作 if(input) { ... } // 操作完毕,关闭文件 input.close(); return 0; }
回到顶部
2. 读入常用操作
-
判断是否到了文末
while(input) { ... }
-
去除前导空格
input >> ws;
-
检查下一个字符,如果到了文末就停止
int c = input.peek(); if(c == EOF) break;
-
读取
int n; input >> n; string str; input >> str; getline(cin, str); ... char sentence[1000]; input.getline(sentence, 1000);
回到顶部
C) 字符串输入、输出流
1. 简介
-
stringstream
- 是
iostream
的子类 - 在对象内维护一个 buffer,可以实现输入和输出
- 流输出函数:将数据写入 buffer
- 流输入函数:从 buffer 读入数据
- 是
-
基本使用方法
#include <sstream> using namespace std; int main() { stringstream ss; ss << "10"; // 将数据写进 ss 的 buffer ss << "0 200"; // 会自动连接字符串 int a, b; ss >> a >> b; // 从 buffer 读取数据,转换成 int return 0; }
回到顶部
2. 对象内的 buffer
-
暂存数据的空间,包含已读取和未读取的内容
-
可以用
ss.str()
来返回 buffer 内的内容(返回类型:string)stringstream ss; ss << "10"; // buffer内有【10】 ss << "0 200"; // buffer内有【100 200】 int a, b; ss >> a; // a = 100,buffer内有【100 200】 ss >> b; // b = 200,buffer内有【100 200】 ss.str(""); // 清空 buffer
-
从以上代码可见,buffer 内的内容不会因为被读取而减少
- 有两个指针在维护着:head 和 tail
- head:指向最后一个内容(下一个位置就是写入新内容的位置)
- tail:指向待读取的第一个元素
- 所有 head 在 tail 的后面,head 和 tail 之间是未读取的元素
回到顶部
3. 实现类型转换
template<class outtype, class intype> outtype convert(intype val) { static stringstream ss; // 避免重复初始化 ss.str(""); // 清空 buffer ss.clear(); // 清空状态位 ss << val; outtype result; // 定义要转换的类型的变量 ss >> result; return result; // 返回转换后的内容 } // 使用 string str = convert<string>(921); int num = convert<int>("122");
回到顶部
这篇关于C++ iostream 输入输出流的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-27TypeScript面试真题解析与实战指南
- 2024-12-27TypeScript大厂面试真题详解与解析
- 2024-12-26怎么使用nsenter命令进入容器?-icode9专业技术文章分享
- 2024-12-26导入文件提示存在乱码,请确定使用的是UTF-8编码怎么解决?-icode9专业技术文章分享
- 2024-12-26csv文件怎么设置编码?-icode9专业技术文章分享
- 2024-12-25TypeScript基础知识详解
- 2024-12-25安卓NDK 是什么?-icode9专业技术文章分享
- 2024-12-25caddy 可以定义日志到 文件吗?-icode9专业技术文章分享
- 2024-12-25wordfence如何设置密码规则?-icode9专业技术文章分享
- 2024-12-25有哪些方法可以实现 DLL 文件路径的管理?-icode9专业技术文章分享