今天重读C++ Primer时,重新回顾了一下C++中iostream标准库,标准库提供了四个标准输入输出流,包括 输入流cin和输出流cout,cerr,clog 。 cerr通常用来输出警告和错误信息给程序的使用者,而clog对象用于产生程序执行的一般信息。
1234
extern istream cin; /// Linked to standard inputextern ostream cout; /// Linked to standard outputextern ostream cerr; /// Linked to standard error (unbuffered)extern ostream clog; /// Linked to standard error (buffered)
iostream标准库中标准输入流中只有cin一个,指的是从输入设备(如键盘)中向程序输入数据,程序通过cin从标准输入流中获取数据。
12345678
#include <iostream>#include <string>int main(){ std::string s; std::cin >> s; std::cout << s << std::endl;}
iostream标准库中提供的输出流有cout,cerr,以及clog三个。
这三个输出流到底有什么区别呢?根据GNU官方的解释,其区别如下:
参考链接:
https://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a00914_source.html
https://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a01140.html#a7e2a2fc4b5924b7292c0566ca4c95463
12345678910111213141516171819202122
#include <iostream>// sleep 10s后输出123int main(){ cout << "123"; sleep(10);}// sleep前输出123int main(){ cerr << "123"; sleep(10);}// sleep前输出123int main(){ clog << "123"; sleep(10);}
从上面的实验结果可以看出,cout与cerr的行为与上述cout和cerr的区别一致,但是 从现象看clog并没有buffered ,这是什么原因呢?
产生上述现象的原因从上面三个输出流的定义可以看出, cout是使用的标准输入(stdout)的缓冲区,clog是使用的标准错误流(stderr)的缓冲区 ,由于stderr的缓冲区大小默认为0,所以虽然clog输出流有缓冲,但是缓冲区大小为0,所以上述效果与无缓冲一致。
可通过设置标准错误流的缓冲区来达到clog缓冲的效果。
12345678910
#include <iostream>#include <stdio.h>#include <unistd.h>char buffer[256];int main(){ setbuf(stderr, buffer); std::clog << "123"; sleep(10);}
在使用endl与\n的作用相同,但是还是有一些区别的。
123456789101112131415161718
#include <iostream>#include <unistd.h>// 直接打印到屏幕上:在sleep前输出123// 重定向到 文件中: 在sleep前输出123int main(){ std::cout << "123" << std::endl; sleep(3);}// 直接打印到屏幕上:在sleep前输出123// 重定向到文件中 : 在sleep后输出123int main(){ std::cout << "123\n"; sleep(3);}
既然\n不刷新缓冲区,那为什么第二个程序在输出到terminal的时候会在sleep前打印123呢?这是由于 当打印到屏幕上的时候,输出流的缓冲为行缓冲,当重定向到文件中时候,输出流缓冲为全缓冲
从上面可以看出标准输出在输出到屏幕和输出到文件中默认的缓冲类型不一致,当输出到屏幕的时候,为行缓冲;当输出到文件的时候为全缓冲。
所以当cout打印到屏幕上的时候,使用cout<<”\n”,也会立即显示结果。