本节开始之前,先科普一下 缓存区 的概念:
假设你现在往文件中要写入很多个字符,我们要知道内存的速度是很快的,硬盘跟不上内存的速度,要是你一个一个字符的写入,会影响效率,所以内存先把一些字符放在一片空间,这篇空间我们称之为 缓存区,等到缓存区积累到了一定的数据/手动操作/系统结束,在将缓存区中的写入文件。

iostream(标准输入,输出流):
1)istream(标准输入流):
理解成从控制面板上敲字符放入缓存区

表示 控制面板 为输入流
其中流有多种情况:
正常读取 ------ goodbit
错误读取(比如类型不匹配,向 int 输入 'x' )------failbit
读取终止(比如文件读取读到底了) ------ eofbit
系统错误(底层出现问题,这个是系统问题,用户操作不会发生) ------ badbit
我们可以使用 cin.good() / cin.fail() /.... 来查询情况,或者看可以 rdstate() & xxxbit 来进行判断
只要你状态不是 goodbit ,就无法写入数据

我现在输入了 字符x 给int 类型的 i,但是i无法读取,输入流的状态就会变成 failbit,后面即使你类型匹配也不会继续写入(读取错误,数据还在流里面)
此时,你要怎么办?
系统给出了 clear() ,来恢复输入流的状态,但是,你要是还想读整型的话,输入流仍然有一个字符,我们必须把这个字符给读取出来,后面才能够正常的读取。
可问题随之而来,我确实能够把字符全部读完string也好while循环也好,你就必然会破坏第一个整型,下面举一个例子
流: xxxx1000 100 100
string读取会有问题,用char来读取,第一个1也会被读取(毕竟你要读取判断后续还要不要读取),实际确实有这个问题。但是,库里面提供了一个函数 peek() ,表示你不会读取流里面的数据。
这样我们就实现了把流修正的方法!!!
ostream(标准输出流):
就是把流里面的东西输出
我们现在来讲一下刷新的概念,我们前面讲到了,缓存区会等到一些条件满足后会自动的刷新流(就是把流里面的数据全部输出出来)
什么意思,好比你先在 cout<<"我是天才";它会先进入缓存区,而不是直接输入到屏幕,只不过一般的编译器都会自动在 cout 后flush一下(毕竟这个是要给你看的,但要是对于文件操作就不一样了,可以很清晰看到差别)
手动的刷新: endl flush
endl:
很多人认为这个就是'\n',但是实际上完全不是。

它的功能是先\n,在调用flush;
flush:
刷新输出流;
输出的方式:

可以看到cout clog cerr wcerr都是可以输出的方式,cout clog cerr 都是narrow char输出,wcerr时宽字符输出,cerr clog 这两个在输出的时候都会自动刷新,便于记录时间。
tie:(只能一个流绑定另一个流)
这个就是把流绑定,什么意思?公用一个流!比如系统时自动cin.tie(cout) ,要是想要解绑怎么办,cin.tie(nullptr),这样就解绑了。因为系统是把cin和cout流绑定了,所以在调用cin的时候会flush一次,避免影响。
sstream:
同样分为isstream 和ostream
这个是比较常用的

你可以想象一下,iostream里面都有一个string的成员变量,你可以构造,也可以调用str来修该这,也可以 ostringstream ,从而修改这个成员变量的值。(如果你想要回复出产设置可以"")
无论你选择的方式是那种都可以通过 istringstram 来写入变量,值得注意的是假如你现在iostream中的str是"xxxxxxxxxx 11111 xxxxxxx 3 333333",他这个输入的形式是" " / " \n" 为间隔输入,由于类型不匹配和输入完了也会进入 failbit eofbit 状态,此时同样需要clear();


所以,可以理解成 输入流是把从某个来源的数据赋值给变量 输出流是把某个变量打印到某个终点!!!