13 Stream(续)
13.10 连接input stream和output stream
1、以tie()完成松耦合
如std::cin.tie(&std::cout);可以保证在cin输入之前,一定会情况output缓冲区,此处即对cout调用flush()。如果参数为NULL,则解除连接。
2、以stream缓冲区完成紧耦合:使不同的stream共享同一个缓冲区
如ostream hexout(cout.rdbuf());用cout的stream缓冲区初始化hexout
注意:只有basic_istream和basic_ostream不销毁缓冲区。其他stream都会销毁它们最初分配的stream缓冲区,但是不会销毁以rdbuf()设置的缓冲区。如std::ofstream file("cout.txt"); file为局部对象,将在程序区段结束时被销毁,其对应的stream缓冲区也一并被销毁。
4、用于读写的stream
std::filebuf buffer; std::ostream out(&buffer); std::istream in(&buffer);
buffer.open("example.txt", std::ios::in | std::ios::out);
两个不同的stream对象in、out分别用于读取和改写,注意读写位置是共享的。
13.11 String stream class——<sstream>
1、型别
istringstream、ostringstream、stringstream、stringbuf。(同样存在wistringstream等)
举例:ostringstream os; os<<"oct:"<<oct<<15; cout<<os.str()<<endl;
13.12 自定义型别的I/O操作符
1、实作一个output操作符
#include <iostream>
#include <sstream>
template <class charT, class traits>
inline std::basic_ostream<charT, traits>&
operator << (std::basic_ostream<charT, traits>& strm, const Fraction& f) //分数的输出
{//先将f输出到字符串流s中,再从s输出到strm中,从而防止格式问题。
std::basic_ostringstream<charT,traits> s;
s.copyfmt(strm);
s.width(0); //防止对于对于16/100,输出为“16 /100”
s<<f.numerator<<'/'<<f.denominator();
strm<<s.str();
return strm;
}
2、实作一个input操作符
#include <iostream>
template <class charT, class traits>
inline std::basic_ostream<charT, traits>&
operator >> (std::basic_ostream<charT, traits>& strm, const Fraction& f) //分数的输入
{
int n, d;
strm>>n;
if(strm.peek() == '/'){
strm.ignore();
strm>>d;
}else{d = 1;}
if(d == 0){
strm.setstate(std::ios::failbit);
return strm;
}
if(strm)
f = Fraction(n,d);
return strm;
}
13.13 stream buffer class
1、成员函数
如果发生错误,sputc()返回traits_type::eof()。
2、缓冲区迭代器——<iterator>
output stream缓冲区迭代器:std::ostreambuf_iterator<char> bufWriter(std::cout);string hello("hello");copy(hello.begin(), hello.end(), bufWriter);
input stream缓冲区迭代器:istreambuf_iterator
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
istreambuf_iterator<char> inpos(cin);
istreambuf_iterator<char> endpos;
ostreambuf_iterator<char> outpos(cout);
while (inpos != endpos) {
*outpos = *inpos;
++inpos;
// ++outpos;
}
return 0;
}
13.14 关于性能
1、cin、cout、cerro、clog等与C标准串流(stdin、stdout、stderr)的同步,可能带来某些不必要的额外负担。
2、I/O是否具备缓冲能力,很大程度上影响了效率。
3、进行无格式I/O时,最好直接使用stream缓冲区。如:cout<<cin.rdbuf();或者cin>>noskipws>>cout.rdbuf();