现在的位置: 首页 > 综合 > 正文

cin的总结

2013年10月04日 ⁄ 综合 ⁄ 共 2668字 ⁄ 字号 评论关闭

cin的总结

近日浏览CSDN,发现经常会有关于cin的问题

参考文献:

http://blog.csdn.net/daineng/archive/2008/04/05/2252730.aspx

http://www.augustcouncil.com/~tgibson/tutorial/iotips.html

http://hi.baidu.com/bdruiruili/blog/item/5966d9958a6eb20c7bf4801f.html

http://www.cplusplus.com/reference/iostream/istream/

 

建议看看:Tips and Tricks for Using C++ I/O (input/output)

cin>><int/float/double> 如果我们输入一个字符,就会导致刷屏的结果。这是因为非数字字符无法被cin接收而一直停留在输入缓冲区,从而导致下一次cin时直接从缓冲区中读取数据,但是字符无法读取,导致死循环。

那么怎么解决呢?

第一、   cin>><int/float/double>后加cin.ignore(); cin.clear();

第二、   cin>><int/float/double >后加fflush(stdin); (需要#include <cstdio> cin.clear()

cin.clear()可以清除输入错误后的相应流状态,而ignorefflush都是起到刷新输入缓冲区的作用(输入的字母留在了缓冲区,cin不能读取,如果不刷新,之后cin还是首先读到字母,导致死循环),从而是cin可以重新接收新的数据。

fflush刷新缓冲区相信大家都不陌生了,这里就不多说了,那么ignore()方法是怎样操作的呢?

以下参考C++ Reference

ignore()方法原型是:

istream&  ignore ( streamsize n = 1, int delim = EOF );

功能:它从输入序列提取字符并且丢弃它们,ignore方法直到丢弃的字符数达到 n 或者丢弃的字符是 delim 时(注意,delim 也会一起被丢弃),终止函数。

参数:

n            丢弃的最大字符数, 它是 streamsize.整数类型

delim      界限符

返回值:

函数返回 *this

 

流状态有三种:

1)          stream:: badbit

系统级的故障,如无法恢复的读写错误,流通常无法继续使用。

2)          stream::failbit

可恢复的流错误,如在希望获得数值型的数据时输入了字符,

3)          stream::eofbit

文件结束,同时还会设置failbit标志

流有三个函数来测试以上各个流状态:即bad(), fail()eof(),另外流状态是否正常可以用good()来测试;流的状态字可以由rdstate()读出;另外还有两个操作用于改变流的状态:clear()setstate(),但它们的操作结果不怎么符合我们的直觉。(注:C++ Reference中的解释是:Sets a new value for the error control state.

setstate必须有个一个表示流状态的参数,操作结果将使指定的状态位置位(set),其他的状态位不变,无法作reset操作。clear用于设置流的状态为参数指定的状态字,它实际上是个set操作,而不是reset,它的参数有一个默认的值为goodbit,这实际是个0,等价于clear(0); 不带参数调用时就是clear状态,带参数时,并不是我们想象中的reset参数指定的位,而是将整个状态字设置成参数指定的那样。

具体的请看basic_ios.h中的代码:

/* g++ (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) */

void clear(iostate __state = goodbit);

void setstate(iostate __state)

{this->clear(this->rdstate() | __state;}

 

以一个例子作为参考:(C++ Primer里面的一个例子)

#include <stdexcept>

#include <iostream>

#include <cstdio>

using namespace std;

 

int main()

{

int ival;

while(cin>>ival, !cin.eof())

{

    if(cin.bad())

        throw runtime_error("IO stream corrupted");

    if(cin.fail())

    {  

        cout << "rdstate()函数的返回值: " << cin.rdstate() << endl;

        cout << "三个标记位返回的返回值: " << cin.fail() << cin.bad() << cin.eof() << endl;

        cout << "goodbit标记位的返回值: " << cin.good() << endl;

 

        //cin.clear(istream::failbit); // 这样不行

        //cin.clear(istream::failbit ^ cin.rdstate()); // 可以

        //cin.ignore();

        cin.clear();

        fflush(stdin);

        cerr <<"bad data, try again:"<<endl; 

        //system("PAUSE");

        continue;

    }

    cout <<ival <<endl;

}

system("PAUSE");

return 0;

}

上面的例子修正了C++ Primer书上的例子

用了2种方法清除输入错误:

cin.clear();

fflush(stdin);

cin.ignore();

cin.clear();

其中,cin.clear()可以替换为:cin.clear(istream::failbit ^ cin.rdstate());

也许大家对cin.rdstate()不太熟悉,简要说明一下:

它的原型是:iostate rdstate ( ) const;它的功能是返回流的当前内部错误标志,他的返回值是eofbitfailbitbadbitgoodbit的任意组合。

如果有任何错误,请指正!

抱歉!评论已关闭.