zoukankan      html  css  js  c++  java
  • 使用cin获取用户的输入信息

      cin(隶属于istream)是供使用者输入用的标准输入通道,对应于C的stdin。操作系统通常将它和键盘连接,用来接受用户从键盘输入进来的数据。下图描述了cin是如何从键盘获取用户数据的过程:

    来自键盘的输入首先会被送到”输入缓冲区“(streambuf),接受变量然后再从”输入缓冲区“中获取数据。

    输入缓冲区” 通过以下代码获取:

     streambuf* inputBuf = cin.rdbuf();

    可以使用  <<   get()   getline()  三种方式获取用户的输入信息。

    说明:'\t' -- 制表符    ' ' -- 空格   '\n' -- 回车

    cin的一些特点:

    (1)  cin可以通过 空格制表符回车 来界定字符串,也可以自定义界定字符。

    (2)cin在某些情况下会失效(即:无法再通过cin获取用户输入到指定的接受变量中,调用cin中的”>>“、”get“、”getline“函数时,程序不会再挂起等待用户输入)。

    (3)”>>“  使用 空格制表符回车 来界定字符窜。

           ”get“  / ”getline“  默认使用  回车 来界定字符窜(用于读取一行数据),也可自定义界定字符。 

    具体细节见后文分析:

    【<<】

    int x;

    cin << x;

    1. 当键入:”       56“,并回车结束输入,x将被赋值为56,且此时”输入缓冲区“中还会残留一个”\n“。

    2. 当键入:”    \t\t32   \t  “,并回车结束输入,x将被赋值为32,且此时”输入缓冲区“中残留”   \t  \n“。

    3. 当键入:”32   56  78“,并回车结束输入,x将被赋值为32,且此时”输入缓冲区“中残留”   56  78\n“。

    【int get() / istream& get(char& c)】 /*永远都不会失效*/

    如果“输入缓冲区”中有数据,就取出“输入缓冲区”的第一个字节,并返回该字节,且从“输入缓冲区”中删除该字节。

    --如:当”输入缓冲区“为空,这程序会挂起,等待用户输入。

    --如:当”输入缓冲区“为”\n“

    int get()返回‘\n'的ASCII码值

    istream& get(char& c) 返回当前cin对象,c=’\n'。

    然后从“输入缓冲区”中删除‘\n’字符,则当前缓冲区变为空。

    --如:当”输入缓冲区“为”\ts  56\t\n“

    int get()返回‘\t'的ASCII码值

    istream& get(char& c) 返回当前cin对象,c=’\t'。

    然后从“输入缓冲区”中删除‘\t’字符,则当前缓冲区变为“s  56\t\n”。

     

    【istream& get(char* s, int n) / istream& get(char* s, int n, char delim)】

    istream& get(char* s, int n)   以回车来界定字符窜。

    istream& get(char* s, int n, char delim)  通过'char delim' 来指定界定字符。

    这两个函数均会从“输入缓冲区”中获取n-1个字符,而s[n-1]不会被用来接收数据,会被恒置为'\0'。

    /*  以istream& get(char* s, int n) 举例  */

    1. 如果输入缓冲区中的字符数为m(不包括最后一个的'\n'回车符),少于n-1个字符,则余下用'\0'来填充。

    --如:当前的缓冲区为“\tab23\n”,执行get(chs, 10);执行完后,chs = "\tab23\0\0\0\0\0",缓冲区变为:“\n”,cin输入流的状态为有效。

    2. 如果输入缓冲区中的字符数为0(不包括最后一个的'\n'回车符)。

    --如:当前的缓冲区为“\n”,执行get(chs, 3);执行完后,chs="\0",缓冲区变为:“\n”,cin输入流的状态变为失效

    3. 如果输入缓冲区中的字符数为m(不包括最后一个的'\n'回车符),等于n-1个字符。

    --如:当前的缓冲区为“sdrgh23\n”,执行get(chs, 8);执行完后,s = "sdrgh23\0",缓冲区变为:“\n”,cin输入流的状态为有效。

    4. 如果输入缓冲区中的字符数为m(不包括最后一个的'\n'回车符),大于n-1个字符。

    --如:当前的缓冲区为“c ghy4nm\n”,执行get(chs, 5);执行完后,s = "c gh\0",缓冲区变为:“y4nm\n”,cin输入流的状态为有效。

     

    【istream& getline(char* s, int n) / istream& getline(char* s, int n, char delim)】

    istream& getline(char* s, int n)   以回车来界定字符窜。

    istream& getline(char* s, int n, char delim)  通过'char delim' 来指定界定字符。

    这两个函数均会从“输入缓冲区”中获取n-1个字符,而s[n-1]不会被用来接收数据,会被恒置为'\0'。

    /*  以istream& getline(char* s, int n) 举例  */

    1. 如果输入缓冲区中的字符数为m(不包括最后一个的'\n'回车符),少于n-1个字符,则余下用'\0'来填充。

    --如:当前的缓冲区为“\tab23\n”,执行getline(chs, 10);执行完后,s = "\tab23\0\0\0\0\0",缓冲区变为空,cin输入流的状态为有效。

    2. 如果输入缓冲区中的字符数为0(不包括最后一个的'\n'回车符)。

    --如:当前的缓冲区为“\n”,执行getline(chs, 3);执行完后,s = "\0\0\0",缓冲区变为空,cin输入流的状态为有效。

    3. 如果输入缓冲区中的字符数为m(不包括最后一个的'\n'回车符),等于n-1个字符。

    --如:当前的缓冲区为“sdrgh23\n”,执行getline(chs, 8);执行完后,s = "sdrgh23\0",缓冲区变为空,cin输入流的状态为有效。

    4. 如果输入缓冲区中的字符数为m(不包括最后一个的'\n'回车符),大于n-1个字符。

    --如:当前的缓冲区为“c ghy4nm\n”,执行getline(chs, 5);执行完后,s = "c gh\0",缓冲区变为:“y4nm\n”,cin输入流的状态变为失效

    失效 -- 可怕的噩梦

    失效【failbit】意味着接收变量无法再从“输入缓冲区”中获得数据,而且程序也不会挂起以等待用户的键盘输入。

    失效发生后,接收变量不会得到任何值,保持原有的值。

    这种情况下,并需重置状态为【goodbit】,才能使接收变量从“输入缓冲区”中获取数据。

    PS: failbit为4  goodbit为0  还有2钟状态:badbit  eofbit

    获取cin的状态

    int state = cin.rdstate();

    bool isgood = cin.good();  // 是否为goodbit状态

    bool isfail     = cin.fail();     // 是否为failbit状态

    bool isbad   = cin.bad();    // 是否为badbit状态

    bool iseof    = cin.eof();     // 是否为eofbit状态

    设置cin的状态

    int state = 0; cin.setstate(state);

    清除cin的状态   // 即置为goodbit

    cin.clear();

    cin会在下面3种情况下发生失效

    1. 类型不匹配

        初始状态:“输入缓冲区”为空

        double d = 0.0;

        cin >> d;  // 此时从键盘键入“sdr” ,并回车。

        由于双精度类型的数无法接收“sdr”,故会发生失效,且此时的“输入缓冲区”内容为“sdr\n”。

    2. 空数据

        初始状态:“输入缓冲区”为空

        char chs[3] = {'a', 'b', 'c'};

        cin.get(chs, 3); // 此时不输入任何数据,直接按回车键。

        发生失效,且此时的chs = “\0bc”  “输入缓冲区”内容为“\n”。

    3. 接收字符窜长度不够

        初始状态:“输入缓冲区”为空

        char chs[3] = {0};

        cin.getline(chs, 3); // 此时从键盘键入“sdrgh” ,并回车

        发生失效,且此时的chs = “sd\0”  “输入缓冲区”内容为“rgh\n”。

    (全文完  欢迎评论)

  • 相关阅读:
    Codeforces D
    Codeforces C
    Minimal Ratio Tree HDU
    Tian Ji -- The Horse Racing HDU
    Monkey Banana Problem LightOJ
    Rooks LightOJ
    洛谷 P2742 [USACO5.1]圈奶牛Fencing the Cows || 凸包模板
    洛谷 P3382 【模板】三分法
    洛谷 P1438 无聊的数列
    洛谷 P1082 同余方程
  • 原文地址:https://www.cnblogs.com/kekec/p/1777279.html
Copyright © 2011-2022 走看看