精华内容
下载资源
问答
  • C++ I/O库流状态标志位

    千次阅读 2009-07-21 14:21:00
    再来看看输入状态标记状态测试函数、状态设置函数之间的关系: 输入状态标记常量有以下几个: 标记常量 常量含义failbit标记的值eofbit标记的值badbit标记的值转化为10进制ios::

    再来看看输入状态标记位、状态测试函数、状态设置函数之间的关系:

     

    输入状态标记位常量有以下几个:

     

     

    标记位常量

    常量

    含义

    failbit标记位的值

    eofbit标记位的值

    badbit标记位的值

    转化为10进制

    ios::failbit

    输入(输出)流出现非致命错误,可挽回

    1

    0

    0

    4

    ios::badbit

    输入(输出)流出现致命错误,不可挽回

    0

    0

    1

    2

    ios::eofbit

    已经到达文件尾

    0

    1

    0

    1

    ios::goodbit

    流状态完全正常

    0

    0

    0

    0

    下面来解释这张表格:

    ios::failbit    ios::badbit    ios::eofbit    ios::goodbit均为常量,它们任何一个都代表了一种流状态,因此称为“输入状态标记位常量”。

    比如,ios::failbit表示的是流状态为

                               流的failbit标记位值为1,eofbit标记位值为0,badbit标记位的值为0。

             始终牢 记:failbit,badbit,Eofbit组成了流状态

             注意:它们不是failbit、badbit、eofbit、goodbit这四个标记位的存贮变量。

                             

    我们可以用输出语句来验证:

            cout << ios:: failbit << endl;
            cout << ios:: eofbit << endl;
            cout << ios:: badbit << endl;

            cout << ios:: goodbit << endl;

    输出的结果为:

    4

    2

    1

    0

    同样是将3个标记位视为二进制数转化为十进制的原理。

    下面分析clear()函数:

    cin.clear(ios::failbit);

    使 得cin的流状态将按照ios::failbit所描述的样子进行设置:failbit标记位为1,eofbit标记位为0,badbit标记位为0。无 需担心goodbit标记位,failbit、eofbit、badbit任何一个为1,则goodbit为0。(goodbit是另一种流状态的表示方 法)

                                                 

     

    cin.clear(ios::goodbit);

    使得cin的流状态将按照ios::goodbit所描述的样子进行设置:failbit标记位为0,eofbit标记位为0,badbit标记位为0。此时goodbit标记位为1,从另一个角度表示cin的流状态正常。

     

    因此clear() 函数作用是:将流状态设置成括号内参数所代表的状态,强制覆盖掉流的原状态。

     

     

    再来分析一下setstate()函数:

    与clear()函数不同,setstate()函数并不强制覆盖流的原状态,而是将括号内参数所代表的状态叠加到原始状态上。

                             

    比如,假设cin流状态初始正常:

    cin.setstate (ios::failbit);      //在cin流的原状态的基础上将failbit标记位置为1

    cin.setstate (ios::eofbit);     //在上一步结束的基础上,将cin流状态的eofbit标记位置为1

    两条语句结束后,cin的faibit标记位和eofbit标记位均为1,badbit标记位为0

                                                

    对比clear()函数的效果:

    cin.clear (ios::failbit);      //将cin的流状态置为ios::failbit所描述的状态

    cin.clear (ios::eofbit);     //将cin的流状态置为ios::eofbit所描述的状态

    两条语句结束后,cin的eofbit标记位为1,而failbit标记位和badbit标记位为0

    即使两种情况,在执行完各自的第一条语句后,cin的流状态情况相同,但当执行完第二条语句,本质区别就显露出来。

                                                  

                                       

                                            

    最后来看看如何利用rdstate()函数和输入状态标记位常量来判断输入流的状态:

    #include <iostream>
    using namespace std;

    int main()
    {
            int a;
            cin>>a;
            cout<<cin.rdstate()<<endl;
            if(cin.rdstate() == ios::goodbit)
            {
                    cout<<"输入数据的类型正确,无错误!"<<endl;
            }
            if(cin.rdstate() == ios::failbit)
            {
                    cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
            }

            system("pause");
            return 0;
    }

    利用前面所讲的rdstate() 函数返回值原理和输入状态标记位常量表,不难理解:

    rdstate() 函数返回当前流对象的failbit、eofbit、badbit3个标记位状态的十进制值

    输入状态格式常量也是failbit、eofbit、badbit3个标记位状态的十进制值

                               

    比如cin流状态读取错误,即failbit标记位为1,eofbit标记位为0,badbit标记位为0,则:

    cin.rdstate()的返回值为4,而格式常量ios::failbit的十进制也是4

    因此,if(cin.rdstate() == ios::failbit) 判断为Ture

    因此程序当中的两个if语句能有效识别出流状态

                                               

                                         

                                      

                                  

                                  

    再来看看有些许不同的程序:

    #include <iostream>
    using namespace std;

    int main()
    {
             cin.setstate(ios::failbit);

            cin.setstate(ios::eofbit);

     

            cout<<cin.rdstate()<<endl;
            if(cin.rdstate() == ios::goodbit)
            {
                    cout<<"输入数据的类型正确,无错误!"<<endl;
            }
            if(cin.rdstate() == ios::failbit)
            {
                    cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
            }

            system("pause");
            return 0;
    }

    输出结果为:

    6

    请按任意键继续...

    原因为何?

    cin流状态被设置成failbit标记位置为1,eofbit标记位置为1,badbit标记位为0

    那么cin.rdstate()的返回值二进制为110,十进制为6,即输出6。

    参照输入状态标记位常量表:

    ios::goodbit的二进制为000,十进制为0,因此if(cin.rdstate() == ios::goodbit)判断为False

    ios::failbit的二进制为100,十进制为4,因此if(cin.rdstate() == ios::failbit)判断为False

    然后system("pause"); 语句使得输出         请按任意键继续...

                                            

    很有意思吧,cin对象明明failbit标记位为1,但表达式cin.rdstate() == ios::failbit却是False,这就是原因。

    rdstate()函数与输入状态标记位常量的对比是严格按照数值对比的。

                       

     

     

     

     

     

     

     

    另外:关于cin对象,输入内容与接受的变量 完全匹配,部分匹配,完全不匹配的各种情况下,标记位将会如何变化,请参考 http://blog.csdn.net/ygj149078299/archive/2005/11/29/538998.aspx

     

     

     

    不对之处,敬请指教。

     

    原帖:http://blog.csdn.net/ygj149078299/archive/2006/08/18/1090432.aspx

    展开全文
  • 引言【摘自其他文章】:    最近在对公司以前的... 例一:表示某个商家是否支持多种会员卡打折(如有金卡、银卡、其他卡等),项目中的以往的做法是:在每条商家记录中为每种会员卡建立一个标志位字段。如图:
    • 引言【摘自其他文章】:   

         

         最近在对公司以前的一个项目进行调整时发现,数据库中有很多表示“多选状态标识”的字段。“多选状态标识”可能描述的并不十分准确,在这里用我们项目中的几个例子进行说明一下。
          例一:表示某个商家是否支持多种会员卡打折(如有金卡、银卡、其他卡等),项目中的以往的做法是:在每条商家记录中为每种会员卡建立一个标志位字段。如图:


     
          其中蓝色区域的三个整形字段分别表示三种会员卡。当值为“1”时表示当前商家支持这种会员卡打折,反之“0”则表示不支持。
     
          例二:表示系统字典表中某种类型方式,会在哪个功能模块中调用。如某种“支付方式”可能在“收银模块”中会用到,在“结算模块”中也会用到。如图:



          用多字段来表示“多选标识”存在一定的缺点:首先这种设置方式很明显不符合数据库设计第一范式,增加了数据冗余和存储空间。再者,当业务发生变化时,不利于灵活调整。比如,增加了一种新的会员卡类型时,需要在数据表中增加一个新的字段,以适应需求的变化。
     
          因此,我们在重新审视数据库设计时,我的一位同事提出了一种代替方式:将多个状态标识字段合并成一个字段,并把这个字段改成字符串型,对多选状态值以字符串数组的方式保存(一个以逗号分隔的字符串:“1,2,3”)。表的结构变成如下:


     

         “MEMBERCARD”字段中,当存在“1”时表示支持金卡打折,“2”时表示支持银卡打折,“3”表示支持其他卡打折。
          这样调整的好处,不仅消除相同字段的冗余,而且当增加新的会员卡类别时,不需增加新的字段。但带来新的问题:在数据查询时,需要对字符串进行分隔。并且字符串类型的字段在查询效率和存储空间上不如整型字段。
     
          总的来说,上面调整的思路是正确的,但不够自然。我后来考虑了一下,觉得可以用“位”来解决这个问题:二进制的“位”本来就有表示状态的作用。可以用下面各个位来分别表示不同种类的会员卡打折支持:


     
          这样,“MEMBERCARD”字段仍采用整型。当某个商家支持金卡打折时,则保存“1(0001)”,支持银卡时,则保存“2(0010)”,两种都支持,则保存“3(0011)”。其他类似。表结构如图:

     

    我们在编写SQL语句时,只需要通过“位”的与运算,就能简单的查询出想要数据:

    [java] view plain copy
    1. //查询支持金卡打折的商家信息:  
    2. select * from factory where MEMBERCARD & b'0001'  
    3. 或者:  
    4. select * from factory where MEMBERCARD & 1  
    5.   
    6. //查询支持银卡打折的商家信息:  
    7. select * from factory where MEMBERCARD & b'0010'  
    8. 或者:  
    9. Select * from factory where MEMBERCARD & 2  

     

          通过这样的处理方式既节省存储空间,查询时又简单方便。以上sql语句为MySQL的语法,其他数据库方法类似。并且“b'0010'”二进制的表示方式的语法是在5.0以后的版本才有。






    • 实际操作【实战一把】: 

    1. CREATE TABLE `news` (
    2. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    3. `title` varchar(20) NOT NULL COMMENT '文章标题',
    4. `status` int(2) NOT NULL COMMENT '状态 1:是否置顶;2:是否点赞;4:是否推荐',
    5. PRIMARY KEY (`id`)
    6. ) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;



    数据表的原始数据: 


    1. 【更新】status =置顶;
    2. update news set status = status | 1 where id = 1
    3. 【更新】status =点赞; update news set status = status | 2 where id = 1
    4.  
    5. 【更新】status =推荐; update news set status = status | 4 where id = 2



    1. 【选择】status =推荐;
    2. select * from news where status & 4 = 4
     

    1. 【选择】status =置顶&推荐&点赞;;
    2. select * from news where status & 7 = 7
    3. 【选择】status =置顶&推荐;
    4. select * from news where status & 3 = 3
    5. 【选择】status =不置顶&不推荐;
    6. select * from news where status & 1 != 1 and status & 4 != 4

    1. 【选择】status =不置顶|不点赞;
    2. select * from news where status & 1 != 1 or status & 2 != 2



    1. 【更新某记录】status =推荐,为不推荐;
    2. update news set status = status ^ 4 where id =1


    更新前:



     

    更新后:




     

     

    • 后记【位运算】:

    按位与运算

    1. 按位与运算符"&"是双目运算符。
    2. 其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0
    3. 参与运算的数以补码方式出现。
    4. 例如:9&5可写算式如下:
    5. 00001001 (9的二进制补码)
    6. &00000101 (5的二进制补码)
    7. 00000001 (1的二进制补码)
    8. 可见9&5=1
    9. 按位与运算通常用来对某些位清0或保留某些位。
    10. 例如把a 的高八位清 0 ,保留低八位,可作a&255运算(255 的二进制数为0000000011111111)。

    按位或运算

    1. 按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。
    2. 只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。
    3. 例如:9|5可写算式如下:
    4. 00001001
    5. |00000101
    6. 00001101 (十进制为13)
    7. 可见9|5=13


    按位异或运算

    1. 按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1
    2. 参与运算数仍以补码出现,
    3. 例如9^5可写成算式如下:
    4. 00001001
    5. ^00000101
    6. 00001100 (十进制为12)

    求反运算

    1. 求反运算符~为单目运算符,具有右结合性。
    2. 其功能是对参与运算的数的各二进位按位求反。
    3. 例如~9的运算为:
    4. ~(0000000000001001)
    5. 结果为:1111111111110110

    左移运算

    1. 左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0
    2. 例如:
    3. a<<4
    4. 指把a的各二进位向左移动4位。
    5. a=00000011(十进制3),左移4位后为00110000(十进制48)。

    右移运算

    1. 右移运算符“>>”是双目运算符。
    2. 其功能是把“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。
    3. 例如:
    4. a=15
    5. a>>2
    6. 表示把000001111右移为00000011(十进制3)。



    注意:对于有符号数,在右移时,符号位将随同移动。当为正数时,最高位补0,而为负数时,符号位为1,

             最高位是补0或是补1 取决于编译系统的规定。Turbo C和很多系统规定为补1


    展开全文
  • TCP连接状态转换详细描述

    千次阅读 2011-08-10 16:03:29
    1、建立连接协议(三次握手) (1)客户端发送一个带SYN...(2) 服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN标志。因此它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户

    1、建立连接协议(三次握手)

    1)客户端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的报文1

    2) 服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN标志。因此它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯。

    3) 客户必须再次回应服务段一个ACK报文,这是报文段3

    2、连接终止协议(四次握手)
       由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

     (1 TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送(报文段4)。
     (2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。
     (3) 服务器关闭客户端的连接,发送一个FIN给客户端(报文段6)。
     (4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

    CLOSED: 这个没什么好说的了,表示初始状态。

    LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。

    SYN_RCVD: 这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。

    SYN_SENT: 这个状态与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。

    ESTABLISHED:这个容易理解了,表示连接已经建立了。

    FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKETESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。

    FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。

    TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

    CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

    CLOSE_WAIT: 这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。

    LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。

    最后有2个问题的回答,我自己分析后的结论(不一定保证100%正确)

    1、 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

    这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACKSYNACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

    2、 为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?

    这是因为:虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文,并保证于此。


    展开全文
  • C++中负责的输入/输出的系统包括了关于每一个输入/输出操作的结果的记录信息。这些当前的状态信息被包含在io_state类型的对象中。io_state是一个枚举类型(就像open_mode一样),以下便是它包含的值。 goodbit 无...

     C++中负责的输入/输出的系统包括了关于每一个输入/输出操作的结果的记录信息。这些当前的状态信息被包含在io_state类型的对象中。io_state是一个枚举类型(就像open_mode一样),以下便是它包含的值。

    • goodbit 无错误

    • Eofbit 已到达文件尾

    • failbit 非致命的输入/输出错误,可挽回

    • badbit 致命的输入/输出错误,无法挽回

    这四个标记位均为bit位,标记值为0或者1,每个标记位0表示清除,1表示设置

     

    其中failbit,badbit,Eofbit组成了流状态

    当这3个标记位都设置为0,则流状态正常,3个标记位某一个或几个设置为1时,流状态出现相应的问题。

     

    goodbit这个标记位是另一种流状态的表示方法

    failbit,badbit,Eofbit这3个标记位都为0,即流状态无异常,goodbit标记位为1,表示流状态正常

    failbit,badbit,Eofbit这3个标记位任何一个为1,即流状态有异常,goodbit标记位为0,表示流状态非正常

    goodbit含义为:流状态正常  标记位。该位设置为1,表示流状态正常,为0则流状态非正常。

     

     1表示肯定,0表示否定,再结合标记位的名称,即可得出标记位当前状态的含义。

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

                     

    再来看看输入状态标记位、状态测试函数、状态设置函数之间的关系:

    输入状态标记位常量有以下几个:

    标记位常量

    常量

    含义

    failbit标记位的值

    eofbit标记位的值

    badbit标记位的值

    转化为10进制

    ios::failbit

    输入(输出)流出现非致命错误,可挽回

    1

    0

    0

    4

    ios::badbit

    输入(输出)流出现致命错误,不可挽回

    0

    0

    1

    2

    ios::eofbit

    已经到达文件尾

    0

    1

    0

    1

    ios::goodbit

    流状态完全正常

    0

    0

    0

    0

     

    下面来解释这张表格:

     ios::failbit    ios::badbit    ios::eofbit    ios::goodbit均为常量,它们任何一个都代表了一种流状态,因此称为“输入状态标记位常量”。

    比如,ios::failbit表示的是流状态为

                               流的failbit标记位值为1,eofbit标记位值为0,badbit标记位的值为0。

             始终牢记:failbit,badbit,Eofbit组成了流状态

             注意:它们不是failbit、badbit、eofbit、goodbit这四个标记位的存贮变量。

                             

    我们可以用输出语句来验证:

            cout << ios:: failbit << endl;
            cout << ios:: eofbit << endl;
            cout << ios:: badbit << endl; 

            cout << ios:: goodbit << endl;

    输出的结果为:

    4

    2

    1

    0

    同样是将3个标记位视为二进制数转化为十进制的原理。

     

    下面分析clear()函数:

    cin.clear(ios::failbit);

    使得cin的流状态将按照ios::failbit所描述的样子进行设置:failbit标记位为1,eofbit标记位为0,badbit标记位为0。无需担心goodbit标记位,failbit、eofbit、badbit任何一个为1,则goodbit为0。(goodbit是另一种流状态的表示方法)

                                                   

    cin.clear(ios::goodbit);

    使得cin的流状态将按照ios::goodbit所描述的样子进行设置:failbit标记位为0,eofbit标记位为0,badbit标记位为0。此时goodbit标记位为1,从另一个角度表示cin的流状态正常。

    因此clear() 函数作用是:将流状态设置成括号内参数所代表的状态,强制覆盖掉流的原状态。

    再来分析一下setstate()函数:

    与clear()函数不同,setstate()函数并不强制覆盖流的原状态,而是将括号内参数所代表的状态叠加到原始状态上。

                             

    比如,假设cin流状态初始正常:

    cin.setstate  (ios::failbit);      //在cin流的原状态的基础上将failbit标记位置为1

    cin.setstate  (ios::eofbit);     //在上一步结束的基础上,将cin流状态的eofbit标记位置为1

    两条语句结束后,cin的faibit标记位和eofbit标记位均为1,badbit标记位为0

                                                

    对比clear()函数的效果:

    cin.clear  (ios::failbit);      //将cin的流状态置为ios::failbit所描述的状态

    cin.clear  (ios::eofbit);     //将cin的流状态置为ios::eofbit所描述的状态

    两条语句结束后,cin的eofbit标记位为1,而failbit标记位和badbit标记位为0

    即使两种情况,在执行完各自的第一条语句后,cin的流状态情况相同,但当执行完第二条语句,本质区别就显露出来。

                                                  

                                       

                                            

    最后来看看如何利用rdstate()函数和输入状态标记位常量来判断输入流的状态:

    #include <iostream>
    using namespace std;

    int main() 
    {
            int a;
            cin>>a;
            cout<<cin.rdstate()<<endl; 
            if(cin.rdstate() == ios::goodbit)
            {
                    cout<<"输入数据的类型正确,无错误!"<<endl;
            }
            if(cin.rdstate() == ios::failbit)
            {
                    cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
            }

            system("pause");
            return 0;
    }

    利用前面所讲的rdstate() 函数返回值原理和输入状态标记位常量表,不难理解:

    rdstate() 函数返回当前流对象的failbit、eofbit、badbit3个标记位状态的十进制值

    输入状态格式常量也是failbit、eofbit、badbit3个标记位状态的十进制值

                               

    比如cin流状态读取错误,即failbit标记位为1,eofbit标记位为0,badbit标记位为0,则:

    cin.rdstate()的返回值为4,而格式常量ios::failbit的十进制也是4

    因此,if(cin.rdstate() == ios::failbit) 判断为Ture

    因此程序当中的两个if语句能有效识别出流状态

                                               

                                         

                                      

                                  

                                  

    再来看看有些许不同的程序:

    #include <iostream>
    using namespace std;

    int main() 

            cin.setstate(ios::failbit);

            cin.setstate(ios::eofbit);

            cout<<cin.rdstate()<<endl; 
            if(cin.rdstate() == ios::goodbit)
            {
                    cout<<"输入数据的类型正确,无错误!"<<endl;
            }
            if(cin.rdstate() == ios::failbit)
            {
                    cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
            }

            system("pause");
            return 0;
    }

    输出结果为:

    6

    请按任意键继续...

    原因为何?

    cin流状态被设置成failbit标记位置为1,eofbit标记位置为1,badbit标记位为0

    那么cin.rdstate()的返回值二进制为110,十进制为6,即输出6。

    参照输入状态标记位常量表:

    ios::goodbit的二进制为000,十进制为0,因此if(cin.rdstate() == ios::goodbit)判断为False

    ios::failbit的二进制为100,十进制为4,因此if(cin.rdstate() == ios::failbit)判断为False

    然后system("pause"); 语句使得输出         请按任意键继续...

                                            

    很有意思吧,cin对象明明failbit标记位为1,但表达式cin.rdstate() == ios::failbit却是False,这就是原因。

    rdstate()函数与输入状态标记位常量的对比是严格按照数值对比的。

                                       

                                        

                                 

                                

    另外:关于cin对象,输入内容与接受的变量 完全匹配,部分匹配,完全不匹配的各种情况下,标记位将会如何变化,请参考http://blog.csdn.net/ygj149078299/archive/2005/11/29/538998.aspx

    不对之处,敬请指教。

     

    展开全文
  • 首先回顾一下TCP标志位的具体含义。 TCP Flag标志位(控制) 一个TCP包的详细内容: TCP FLAG 标记占1.5个byte,12bit(4bit+8bit,前半个byte与Header Length公用)。 12bit中前三个bit是保留,默认为...
  • C++中的文件输入/输出(4)原作:Ilia Yordanov, loobian@cpp-home.com 检测输入/输出的状态标志 在此我不打算解释“标志(flags)”一词的含义,不过假如你真的完全不理解关于这方面的概念,那么将本章读过一遍...
  • 8086标志寄存器笔记

    千次阅读 2017-08-23 00:40:07
    8086标志寄存器(flag)有16,其中存储的信息称为程序状态字(PSW),flag是按起作用的,也就是说它的每一都有专门的含义,记录特定的信息,0-15都意义 flag的1,3,512,13,14,15在8086CPU 没有使用,不具有任何...
  • 汇编学习--7.13--标志寄存器

    千次阅读 2012-07-13 14:52:11
    标志寄存器 CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都可能不同)具有三种作用: ...8086CPU的标志寄存器有16,其中存储的信息通常被称为程序状态字(PSW)。简称flag。
  • Bugzilla的bug状态

    千次阅读 2013-11-04 20:47:03
    正确权限的用户可以确认这个bug,把它的状态改成"NEW”。bug经常直接被解决并被标志成"RESOVLED”,但是通常的情况是bug需要先被指定这个bug的属主开发人员确认。 NEW----bug已经被加入到属主的bug列表中
  • TCP连接的状态详解以及故障排查

    万次阅读 多人点赞 2014-08-20 07:06:38
    我们通过了解TCP各个状态,可以排除和定位网络或系统故障时大有帮助。(总结网络上的内容) 1、TCP状态 了解TCP之前,先了解几个命令: linux查看tcp的状态命令: 1)、netstat -nat 查看TCP各个状态的数量 2)...
  • fcntl函数可以改变已打开文件的性质。函数原型如下: #include int fcntl(int filedes, int...当第二个参数cmd=F_SETFL时,它的作用是设置文件描述符filedes的文件状态标志,这时第三个参数为新的状态标志。 返回值
  • pom.xml配置文件中所有标签及作用简单描述

    千次阅读 多人点赞 2017-03-21 18:26:02
    我转载的是关于pom.xml文件中会使用到的基本上所有的标签以及标签的作用简单描述。 可能我们自己的项目所使用到的标签总数量不及此文的一半。 我转载仅为方便你我他学习之用,众喷子们,还请指下留情,轻喷。 因为此...
  • 四、边界标志填充算法 在光栅显示平面上,多边形是封闭的,它是用某一边界色围成的一个闭合区域,填充是逐行进行的,即用扫描线逐行对多边形求交,在交点对之间填充。边界标志填充算法就是在逐行处理时,利用边界或...
  • 报表描述符定义了执行设备功能的数据格式和使用方法。 报表描述符和 USB 的其他描述符是不一样的,它不是一个简单的表格, 报表描述符是 USB 所有描述符中最复杂的 。报表描述符非常复杂而有弹性,因为它需要处理...
  • 一、tcp状态转换图 下图对排除和定位网络或系统故障时大有帮助,也帮助我们更好的编写Linux程序,对嵌入式开发也有指导意义。    先回顾一下TCP建立连接的三次握手过程,以及关闭连接的四次握手过程:   1、...
  • 也就是说,设置Refreshing状态时,设置内部状态和设置UI状态被分离开了,如果在中间插入了设置内部状态(比如Idle)的操作可能会导致内部状态和UI状态不一致的问题。另外,MJRefreshendRefreshing方法中“设置状态为...
  • 【DIRECTX状态详解】

    千次阅读 2015-03-02 23:09:15
    本节描述图形流水线用到的所有不同类型的状态。 渲染状态 取样器状态 纹理层状态 状态块 渲染状态 设备渲染状态控制Microsoft®Direct3D®设备光栅化模块的行为,它们通过改变渲染状态
  • NTSTATUS状态码 详细解说

    千次阅读 2018-08-18 13:04:31
    描述 0x00000000 状态成功 手术顺利完成。 0x00000000 状态等待_0 调用方为WaitType指定WaitAny,对象数组中的Dispatcher对象之一已设置为已发出信号的状态。 ...
  • 进程的三种状态及转换

    千次阅读 2014-03-08 21:48:05
    1.进程的三种基本状态  进程在运行中不断地改变其运行状态。通常,一个运行进程必须具有以下三种基本状态。  就绪(Ready)状态  当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的...
  • 接着各个节点又被划分为内存管理区域, 一个管理区域通过struct zone_struct描述, 其被定义为zone_t, 用以表示内存的某个范围, 低端范围的16MB被描述为ZONE_DMA, 某些工业标准体系结构中的(ISA)设备需要用到它, 然后...
  • 怎么查看mysql数据库的当前状态

    千次阅读 2019-05-24 18:48:04
    主要是看当前机器cpu的使用,磁盘使用,io等状态。这个需要使用linux的一些指令,如top,iostat,不了解这两个指令的可以借鉴https://blog.csdn.net/h2604396739/article/details/90521347 2 mysql自身状态 一、...
  • DIRECT3D状态详解

    千次阅读 2011-01-06 22:01:00
    本节描述图形流水线用到的所有不同类型的状态。渲染状态取样器状态纹理层状态状态块渲染状态 设备渲染状态控制Microsoft® Direct3D®设备光栅化模块的行为,它们通过改变渲染状态的属性,使用何种类型的...
  • 浅谈 non-blocking I/O Multiplexing + poll/epoll 的正确使用

    万次阅读 多人点赞 2013-10-09 23:48:14
    这篇文章来谈谈如何正确使用non-blocking I/O Multiplexing + poll/epoll。 1、首先来回顾下poll / epoll 函数的原型 #include int poll(struct pollfd *fds, nfds_t nfds, int timeout); ...
  • 进程是具有独立功能的程序关于 某个数据集合上 的一次运行活动,是系统进行 资源分配和调度的独立单位 。又称为任务(Task or Job) 特点: 程序的 一次执行过程 是正在运行程序的抽象 将一个CPU变幻成...
  • MSG_PEEK标志

    千次阅读 2014-06-06 21:34:29
    MSG_PEEK标志可以用来读取套接字接收队列中可读的数据,一些情况会用到它,比如为了避免不阻塞而先检查套接字接收队列中可读的数据长度,再采取相应操作。 当然,不阻塞也可采取其他的方法,例如非阻塞式I/O。 MSG_...
  • java中锁的四种状态

    千次阅读 多人点赞 2019-06-20 16:12:07
    原来已经获取了偏向锁的线程也可能尚未执行完同步代码块, 偏向锁依旧有效, 此时对象就应该被转换为被轻量级加锁的状态 轻量级加锁过程: 首先根据标志位判断出对象状态处于不可偏向的无锁状态( 如下图) 在当前...
  •  例一:表示某个商家是否支持多种会员卡打折(如有金卡、银卡、其他卡等),项目中的以往的做法是:在每条商家记录中为每种会员卡建立一个标志位字段。如图:    其中蓝色区域的三个整形字段分别表示三种...
  • TCP 连接状态

    千次阅读 2017-04-14 14:07:37
    TCP十一种状态 全部11种状态 1. 客户端独有的:(1)SYN_SENT (2)FIN_WAIT1 (3)FIN_WAIT2 (4)CLOSING (5)TIME_WAIT 。 2. 服务器独有的:(1)LISTEN (2)SYN_RCVD (3)CLOSE_WAIT (4)LAST_ACK 。...
  • 文章目录一、TCP报文二、三次握手三、四次挥手四、TIME_WAIT状态五、connect()、listen()和accept()三者之间的关系六、三次握手、四次挥手总结七、滑动窗口(流量控制)八、拥塞控制九、粘包问题十、TCP状态转换图 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 93,170
精华内容 37,268
关键字:

关于状态标志位的正确描述是