【C++ IO机制】标准输入输出 ①
标准输入输出
1. cin 原型:
template <class CharT, class Traits = std::char_traits<CharT>> class basic_istream : virtual public std::basic_ios<CharT, Traits>
2. cout 原型:
template <class CharT, class Traits = std::char_traits<CharT>> class basic_ostream : virtual public std::basic_ios<CharT, Traits>
3. cerr 原型:
template <class CharT, class Traits = std::char_traits<CharT>> class basic_ostream : virtual public std::basic_ios<CharT, Traits>
【注意】
extern istream cin; // Linked to standard input extern ostream cout; // Linked to standard output extern ostream cerr; // Linked to standard error (unbuffered)
iostream 现在是模板化的,同时支持窄字符和宽字符。下图是现在的继承体系,同时画出了 fstreams 和 stringstreams。图中方框的第二行是模板的具现化类型,也就是我们代码里常用的具体类型(通过 typedef 定义)。
这个继承体系糅合了面向对象与泛型编程,但可惜它两方面都不讨好。
再进一步加深了解,发现还有一个平行的 streambuf 继承体系,fstream 和 stringstream 的不同之处主要就在于它们使用了不同的 streambuf 具体类型。
每个流(cout/cin/clog/ifstream/ofstream
)都有自己的流缓冲区(streambuf
)。通过rdbuf
接口可以获取当前的streambuf,也可以设置新的streambuf。
例如我们可以修改std::cout
和std::stringstream
使用同一块缓冲区:
1 #include <stdio.h> 2 #include <iostream> 3 #include <sstream> 4 5 int main() 6 { 7 std::stringstream ss; 8 std::streambuf *cout_buf = std::cout.rdbuf(); 9 std::cout.rdbuf(ss.rdbuf()); 10 //使用了新的缓冲区后,字符串不会输出到屏幕,而是由stringstream管理 11 std::cout << "std::cout hello world"; 12 13 // printf std::cout hello world 14 printf("printf %s\n", ss.str().c_str()); 15 16 std::cout.rdbuf(cout_buf); 17 18 return 0; 19 }
输出:
参考资料