输入输出流,看似复杂却更好用----小话c++(2) (二)

2014-11-24 12:01:29 · 作者: · 浏览: 1
__ostream_type&
operator<<(bool __n)
{ return _M_insert(__n); }

__ostream_type&
operator<<(short __n);[cpp] __ostream_type&
put(char_type __c);

__ostream_type&
flush();
__ostream_type&
put(char_type __c);

__ostream_type&
flush();
可以看出,它实现了具体的输出不同类型数据以及刷新等操作。同时,也可以看到,它们均继承了basic_ios类,下面是它的部分实现:[cpp] template
class basic_ios : public ios_base
template
class basic_ios : public ios_base[cpp] void
clear(iostate __state = goodbit);

bool
good() const
{ return this->rdstate() == 0; }

bool
eof() const
{ return (this->rdstate() & eofbit) != 0; }

bool
fail() const
{ return (this->rdstate() & (badbit | failbit)) != 0; }

bool
bad() const
{ return (this->rdstate() & badbit) != 0; }
void
clear(iostate __state = goodbit);

bool
good() const
{ return this->rdstate() == 0; }

bool
eof() const
{ return (this->rdstate() & eofbit) != 0; }

bool
fail() const
{ return (this->rdstate() & (badbit | failbit)) != 0; }

bool
bad() const
{ return (this->rdstate() & badbit) != 0; }

可以看出,basic_ios内部实现了basic_istream和basic_ostream类共同可能需要执行的地方:缓冲区状态等。basic_ios继承了ios_base类,它的部分实现如下:[cpp] class ios_base
class ios_base[cpp]
inline streamsize
precision() const { return _M_precision; }

inline streamsize
precision(streamsize __prec)
{
streamsize __old = _M_precision;
_M_precision = __prec;
return __old;
}

inline streamsize
width() const { return _M_width; }

inline ios_base&
boolalpha(ios_base& __base)
{
__base.setf(ios_base::boolalpha);
return __base;
}

inline streamsize
precision() const { return _M_precision; }

inline streamsize
precision(streamsize __prec)
{
streamsize __old = _M_precision;
_M_precision = __prec;
return __old;
}

inline streamsize
width() const { return _M_width; }

inline ios_base&
boolalpha(ios_base& __base)
{
__base.setf(ios_base::boolalpha);
return __base;
}
它主要实现了精度控制、宽度等一些更基本的流控制。
而对于iostream类,它继承了istream和ostream.

[cpp] template
class basic_iostream
: public basic_istream<_CharT, _Traits>,
public basic_ostream<_CharT, _Traits>
template
class basic_iostream
: public basic_istream<_CharT, _Traits>,
public basic_ostream<_CharT, _Traits>可以看出,它可以实现istream和ostream的所有功能。还有,ifstream, ofstream, fstream, istrstream, ostrstream, strstream以及strstreambase和上面各个类的继承关系可以类似分析。
总的说来,按照输入输出的最终功能,将它的实现抽象出共同完成的部分以及单独完成的部分,即为上面的设计图。


Q:istrstream, ostrstream以及strstream,它们究竟要实现什么

A: 把它们和c中的sprintf, sscanf联系起来就理解了。它们只不过是要实现如何对内存中一块所谓的字符串进行拼接或者取出的操作。不过c++已经将这几个类标记为废弃了,类似功能的类为stringstream, istringstream, ostringstream.如下举个例子:

因为mac下xcode对于stringstream的处理稍有bug, 下面直接使用gcc4.2.1编译:

[cpp] #include
#include

#define COUT_ENDL(str) std::cout << #str << " is " << (str) << std::endl;

int main()
{
std::stringstream s;
int i = 128;
char buf[32];
int value;
s << "hello" << " " << i;
s >> buf;
s >> value;
COUT_ENDL(buf)
COUT_ENDL(value)
return 0;
}
#include
#include

#define COUT_ENDL(str) std::cout << #str << " is " << (str) << std::endl;

int main()
{
std::stringstream s;
int i = 128;
char buf[32];
int value;
s << "hello" << " " << i;
s >> buf;
s >> value;
COUT_ENDL(buf)
COUT_ENDL(value)
return 0;
}保存为stringstream.cpp, 使用g++ stringstream.cpp -o stringstream编译,运行:[plain] buf is hello
value is 128
buf is hello
value is 128
其实,很简单,使用 << 将后面的数据存入字符串中,注意是用字符串格式,i是个整形依然被转换成字符串格式; >> 将数据提取出来,到后面的变量中。

Q: 感觉c++的输入输出的形式很多很多,而且有的地方可能会混淆一些操作,为什么