zoukankan      html  css  js  c++  java
  • cin作为判断条件时(关于cin的理解)

    关于cin

    cin是istream类的对象,它是从标准输入设备(键盘)获取数据,(此外,cout是流的对象,即ostream类的对象,cerr是标准错误输出流的对象,也是ostream 类的对象。这里的标准输出和标准错误输出指的是终端的屏幕) 程序中的变量通过流提取符">>"从流中提取数据。流提取符">>"从流中提取数据时跳过输入流中的空格、tab键、换行符等空白字符。注意:只有在输入完数据再按回车键后,该行数据才被送入键盘缓存区,形成输入流,提取运算符">>"才能从中提取数据。需要注意保证从流中读取数据能正常运行。
       

    例如:
        int a,b;
         cin>>a>>b;     

    若从键盘中输入21 abc回车,变量a从输入流中提取整数21,提取操作成功,此时cin流出于正常状态。但在变量b准备提取一个整数时,遇到了字母a,显然提取操作失败了,此时,cin流被置为出错状态。只有在正常状态,才能从输入流中提取数据。

    字符输入的流成员函数
      除了可以用cin输入标准类型的数据外,还可以用istream类流对象的一些成员函数,实现字符的输入。如cin.get(),cin.getline(字符数组(或字符指针),字符个数n,终止标志字符)

    eof函数
      eof是end of file 的缩写,表示“文件结束”。从输入流读取数据,如果到达文件末尾(遇到文件结束符),eof函数值为非零值(表示真),否则为0(表示假)。

    peek函数
      peek是观察的意思,peek函数的作用是观测下一个字符。   调用形式为c=cin.peek();

    putback函数
      调用形式为cin.putback(ch)   其作用是将前面用get或者getline函数从输入流中读取的字符ch返回到输入流,插入到当前指针的位置,供后面读取。

    ignore函数
      调用形式为cin.ignore(n,终止字符)   函数作用是跳过输入流中n个字符,或在遇到指定的终止字符时提前结束(此时跳过包括终止字符在内的若干字符)。

    cin的状态标示符:

    常量

    含义

    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

    分别对应cin.fail(),cin.bad(),cin.eof(),cin.good()

    cin.rdstate()对应十进制。

    while(cin>>n)

         最近在看C++,学到了标准库这一章,看到cin的时候,我们经常看到很多的代码中会有这么一段while(cin>>x){ ......}。这里我们最关注的问题是while括号里面cin>>x他每次输入的时候返回的是什么值呢。所以我们也就会问cin的返回值是什么。我也看到很多像我这样的新手问这样的问题,下面说下我个人的见解,如有不当之处,还请指正!

        其实我倒觉得我们这个问题问错了,我们不应该问cin返回值是什么,我觉得我们应该关注">>"输入操作符,其实是它到底返回了什么。因为cin是标准输入istream的一个对象,一个对象能返回什么吗?对象有返回值吗?好像没有吧!在C++primer里面讲到过,cin>>x>>y。有这么一行代码,我们讨论下">>"这个输入操作符,这个操作符接收一个istream对象作为其做操作数,接收一个对象作为其右操作数。">>"操作符返回其左操作数作为结果,这样也就可以解释为什么上面可以将两个输入操作合并了。因为cin>>x返回cin对象,接着又可以进行cin>>y。所以我们就可以顺利进行输入了。所以我们再来看上面的那个while循环,里面的cin>>x,返回的是cin对象(注意是输入操作符“>>”返回),所以返回的也就可以认为是流本身了。我们再来看下他什么时候退出循环。因为我们已经知道了括号里面的返回值了,所以我们看看它什么时候退出循环。

        输入(cin)缓冲是行缓冲。当从键盘上输入一串字符并按回车后,这些字符会首先被送到输入缓冲区中存储。每当按下回车键后,cin 就会检测输入缓冲区中是否有了可读的数据,这种情况下cin对键盘上是否有作为流结束标志CTRL+Z或者CTRL+D,其检查的方式有两种:阻塞式以及非阻塞式。这里借用一点网上搜到的资料,

        阻塞式检查方式指的是只有在回车键按下之后才对此前是否有 Ctrl+Z 组合键按下进行检查,非阻塞式样指的是按下 Ctrl+D 之后立即响应的方式。如果在按 Ctrl+D 之前已经从键盘输入了字符,则 Ctrl+D的作用就相当于回车,即把这些字符送到输入缓冲区供读取使用,此时Ctrl+D不再起流结束符的作用。如果按 Ctrl+D 之前没有任何键盘输入,则 Ctrl+D 就是流结束的信号。 
        阻塞式的方式有一个特点:只有按下回车之后才有可能检测在此之前是否有Ctrl+Z按下。还有一个特点,   Windows下是不用CTRL+D的,如果在你的程序中使用CTRL+D的话,如果你还有要输入的数据的话,会直接挂掉的,不能再输入了。Windows下是使用CTRL+Z的。 在你输入CTRL+Z后,括号里面的数据变为0了。来看一段程序:(vc6.0上运行)

    #include <iostream>
    using namespace std;
    int main(void)
    {
       int   i;
      cout<<(cin>>i)<<endl;
      return  0;
    }

       当你按下CTRL+Z后,按下两次回车,就可以得到结果0.所以上面的while会退出循环。但是当你在你的程序中输入数据的时候,你要结束输入,你输完数据直接回车,再按下CTRL+Z,再按下回车就可以结束了。因为前面说过如果输入缓冲区中有可读的数据则不会检测 Ctrl+Z(因为有要读的数据,还不能认为到了流的末尾)。还有一点需要知道,Ctrl+Z产生的不是一个普通的ASCII码值,也就是说它产生的不是一个字符,所以不会跟其它从键盘上输入的字符一样能够存放在输入缓冲区。!

       在理解cin功能时,不得不提标准输入缓冲区。当我们从键盘输入字符串的时候需要敲一下回车键才能够将这个字符串送入到缓冲区中,那么敲入的这个回车键( )会被转换为一个换行符 ,这个换行符 也会被存储在cin的缓冲区中并且被当成一个字符来计算!比如我们在键盘上敲下了123456这个字符串,然后敲一下回车键( )将这个字符串送入了缓冲区中,那么此时缓冲区中的字节个数是7 ,而不是6。

           cin读取数据也是从缓冲区中获取数据,缓冲区为空时,cin的成员函数会阻塞等待数据的到来,一旦缓冲区中有数据,就触发cin的成员函数去读取数据。当cin>>从缓冲区中读取数据时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin>>会将其忽略并清除,继续读取下一个字符,若缓冲区为空,则继续等待。但是如果读取成功,字符后面的分隔符是残留在缓冲区的,cin>>不做处理。 

           使用一个istream的对象作为条件时,效果是检查流的状态。若流有效,则检测成功,返回true。当遇到文件结束符或者无效的输入(比如用一个字符来作为一个整型数的输入时),istream的对象状态会变为无效。

    总结:cin是一个istream的对象,判断时会检查流的状态,流有效返回ture,当文件结束符或者无效的输入(比如用一个字符来作为一个整型数的输入时)时,返回false。

    注:windows环境下ctrl+z 结束输入

          ctrl+c直接结束数据(数据不会进去缓存区)

     个人理解,有错误还望指出。

     

  • 相关阅读:
    (31)对象的克隆
    (30)批处理文件.bat
    06.v-on的修饰符
    06.v-on参数问题
    06.2修饰符补充
    06.1v-on基础+-.
    03.data数据对象
    02.el挂载点
    02.5v-pre指令
    02.4v-text指令
  • 原文地址:https://www.cnblogs.com/seamusopen/p/8447301.html
Copyright © 2011-2022 走看看