使用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”。

(全文完  欢迎评论)

原文地址:https://www.cnblogs.com/kekec/p/1777279.html