cin/cout 是带缓冲的输入输出,
这里cin>>%int_type_var%,如果输入的是字母,和int类型不匹配,那么输入的字母就会被滞留在缓冲区中,直至被正常接受,int_type_var没有接收到数值因而被系统自动赋值为0,循环进行到下次输入时,由于缓冲区有数据(第一次滞留的字母),所以系统认为已经发生输入动作,控制权没有转移到键盘,但由于类型仍然不能匹配,所以字母依然滞留在缓冲区中,int_type_var依然没有接收到合法数值,由此往复,发生死循环...
cin.get不同的是>>作为流的一种操作,他会对流中的数据进行格式化等操作,要完成的内容要比get这类函数要复杂,所以在做之前要先创建sentry对象,他会完成>>与get一样的功能,但是区别在
他会做很多错误检测,和标志检测,如果成功,那么>>则什么都不做,直接得到sentry返回的结果,如果sentry有错误,>>还会在做一次
通过类型转化,将int转化为一个CHK_T<int>类型的对象,再用重载的oprator<<检测输入合法性.注意,如果不这样的话,直接这样做不是行的:
这样不行,因为cin >> i;将调用标准库中的istream& operator>>(istream &in, int &t);
template <typename T>
istream& operator>>(istream &in, T &t)
{
...
}
别人写的一个Check Input class:
class ChkInput
{
public:
ChkInput(istream &in) : m_in(in) {}
template <typename T>
ChkInput& operator>>(T &t)
{
// 输入数据前类型合法性检测
while(!(m_in >> t))
{
m_in.clear();
m_in.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "Oops,bad input data,try again!" << endl;
}
return *this;
}
private:
istream& m_in;
};
int main()
{
int i = -1;
long j = -2;
cout << "input a integer number and a long number:";
ChkInput(cin) >> i >> j;
cout << "i = " << i << ", j = " << j << endl;
system("pause");
return 0;
}
//说明:标准的decorate模式要求decorate class 与被装饰的class从同一个基类继承而来,再在decorate class添加附的操作;这里为了简单起见新建了一个decorate来解决问题,但与标准decorate模式的思路是一致的.
直接运用streambuf常常比使用istream成员函数更好。由于不需构造sentry对象,因而避免额外开销,似的streambuf在读取单个字符或者字符序列时更加高效。或者可以使用迭代器istreambuf_iterator,他提供一个streambuf迭代器接口。
(1).streambuf操作函数(关于streambuf的功能见I/O流简介)
AA.写入函数:
sputc(c) 将字符c送入stream缓冲区,出错返回traits_type::eof()。
sputn(s,n) 将字符序列s中的n个字符送入stream缓冲区
BB.读取函数:
in_avail() 返回有效字符的下界(lower bound)
sgetc() 返回当前字符,不耗用它(without consuming it)
sbumpc() 返回当前字符并耗用它(consuming it)
snextc() 耗用当前字符并返回下一个字符
sgetn(b,n) 读取n个字符,并把它们放到存储区b,返回实际读取的字符
sputbanckc(c) 将字符c返回stream缓冲区
sungetc() 退回至前一个字符
------------------------------------
in_avail()可以用来确定至少有多少个有效字符,除非stream已经到达stream尾部,否则始终存在一个当前字符。sgetc()获得当前字符且不必移至下一字符,sbumpc()取得当前字符,然后移至下一字符且使下一字符成为当前字符,snextc()将下一字符当作当前字符并且读取之。这三个函数出错均返回traits_type::eof()。其余三个均很好理解。
CC.无法分类者
pubimbue(loc) 为stream缓冲区安装local loc
getloc() 返回当前的(current)locale
pubseekpos(pos) 将当前(current)位置重新设定为某绝对位置
pubseekpos(pos,which) 同上,且可以指定I/O方向
pubseekoff(offset,rpos) 将当前位置重新设定为另一位置的相对位置
pubseekoff(offset,rpos,which) 同上,且可以指定I/O方向
pubsetbuf(b,n) 影响缓冲行为
(2)Stream缓冲区迭代器(Buff Iterators)
AA.
OutPut Streambuf Iterator:
Declare:
ostream_iterator<char>(ostream);
ostream_iterator<char>(buff_ptr);
Operator:
*iter;
iter = c;
++iter;
iter++;
failed();
BB.
InPut Streambuf Iterator:
Declare:
istream_iterator<char>();
istream_iterator<char>(ostream);
istream_iterator<char>(buff_ptr);
Operator:
*iter;
++iter;
iter++;
iter1.equal(iter2);
iter1 == iter2;
iter1 != iter2;
iter++;
全局性的stream对象
istream cin 从标准input通道读入数据
ostream cout 将一般数据写至output通道
ostream cerr 将错误信息写至标准error通道
ostream clog 将日志信息写至标准logging通道
另:wcin wcout wcerr wclog实现宽字符下的上述功能。
Streams的状态
状态常数
goodbit:OK
eofbit: 遇到end-of-file
failbit: 错误,某个I/O失败
badbit: 毁灭性错误:未定义(不确定)的状态
成员函数
goog() 正常无误返回true
eof() 遇到end-of-file返回true
fail() 发生错误返回true
bad() 发生毁灭性错误返回true
rdstate() 返回当前已设立所有标志
clear() 清楚所有标志
clear(state) 清楚所有标志后设立state标志
setstate(state) 加设state标志
bool测试Stream状态
operator void* () 等价于 !fail()
operator !() 等价于 fail()
例如:
//while the standard input is OK
while(std::cin)
{
//……………………..
}
Streams状态和异常
exception(flags) 设定“会引发异常”的标志
exception() 返回引发异常的标志
posted on 2007-06-08 11:17
Tempwmk 阅读(1510)
评论(0) 编辑 收藏 引用