前言

总结一波cin的详细用法

正文

cin介绍

cin 是 C++ 的标准输入流对象,即 istream 类的对象。cin 主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。此外,cout 是输出流对象,即 ostream 类的对象,cerr 是标准错误输出流的对象,也是 ostream 类的对象。这里的标准输出指的是终端的屏幕。

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

cin读取数据也是从缓冲区中获取数据,缓冲区为空时,cin的成员函数会阻塞等待数据的到来,一旦缓冲区中有数据,就触发cin的成员函数去读取数据。

1.cin>>

cin可以连续从键盘读取想要的数据,以空格、tab或换行作为分隔符,即碰到分隔符,表示一个输入的结束。当cin>>从缓冲区中读取数据时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin>>会将其忽略并清除,继续读取下一个字符,若缓冲区为空,则继续等待。但是如果读取成功,字符后面的分隔符是残留在缓冲区的,cin>>不做处理。

int a,b;
string c;
cin>>a>>b;
cin>>c;

输入是1[enter]2[enter]a[enter],则a=1.b=2,c=a;输入是[enter][enter]1[enter]2a,则a=1,b=2,c=a;其中cin>>自动忽略了一开始的分隔符,直到遇到值赋给a,而且往后也是cin>>,只是写成了连续赋值的形式,所以b之前的分隔符也被忽略了。而且如果输入是1[enter]a[enter]因为输入a和定义的int型b类型不符,所以不会赋值成功。

为什么说cin>>对字符后面的残留在缓冲区的分隔符不做处理呢,我们可以验证下,后面会说到cin.getline()读取数据时,并非像cin>>那样忽略第一个换行符,getline()发现cin的缓冲区中有一个残留的换行符,不阻塞请求键盘输入,直接读取,送入目标字符串后,再将换行符替换为空字符’\0’

int a;
string b;
cin>>a>>b;
cout<<a<<b;
//第二种
cin>>a;
getline(cin,b);
cout<<a<<b

输入:1[enter]hello[enter] 如果是用cin>>a>>b输入的话,这样两个>>都会忽略字符前的分隔符的,结果为a=1,b=“hello”,但是如果是第二个输入的方式,则getline不会将1后面的[enter]忽略掉,它会将其读取到b中,因为是换行符,所以替换成’\0’,代表结束,则hello会被屏蔽,但是依然存放在缓冲区里,这个时候再来一个getline,才会读取还在缓冲区中的b。

2.cin.get()

cin.get()从输入缓冲区读取单个字符时不忽略分隔符,直接将其读取cin.get()的返回值是int类型,成功:读取字符的ASCII码值,遇到文件结束符时,返回EOF,即-1,Windows下标准输入输入文件结束符为Ctrl+z,Linux为Ctrl+d。cin.get(char var)如果成功返回的是cin对象,因此可以支持链式操作,如cin.get(b).get(c)。

char a,b;
a=cin.get();
cin.get(b);

输入e[enter],这样a=e,b=[enter],因为get不忽略分隔符。

同时cin.get()还可以读取一行

char a;
char array[20]; 
cin.get(array,20);
cin.get(a);
cout<<array<<" "<<a<<endl;

输入:12345[enter] 输出:array=12345,a=[enter];读取一行时,遇到换行符时结束读取,但是不对换行符进行处理,换行符仍然残留在输入缓冲区。第二次由cin.get()将换行符读入变量a,换行符的ASCII码值为10。这也是cin.get()读取一行与使用getline读取一行的区别所在。getline读取一行字符时,默认遇到’\n’时终止,并且将’\n’直接从输入缓冲区中删除掉,不会影响下面的输入处理。

cin.get(str,size);读取一行时,只能将字符串读入C风格的字符串中,即char*,但是C++的getline函数可以将字符串读入C++风格的字符串中,即string类型。鉴于getline较cin.get()的这两种优点,建议使用getline对一行进行读取。

3.cin.getline()

cin.getline(),从标准输入设备键盘读取一串字符串,并以指定的结束符结束,一般为字符数组赋值。cin.getline()实际上有三个参数,cin.getline(接受字符串的字符串地址,接受个数,结束字符) ,当第三个参数省略时,系统默认为’\0’

#include <iostream>
using namespace std;

int main()
{
	char array[20];
	cin.getline(array,7); 
	//或者指定结束符
	//cin.getline(array,7,'\n');
	cout<<array<<endl;
	return 0;
}


因为读入七个字符,字符串结尾’\0’需要占一位,因此输出为123[空格]45。
cin.getline()与cin.get()的区别是,cin.getline不会将结束符或者换行符残留在输入缓冲区中。

4.getline()

#include <string> 
#include <iostream>
using namespace std;
int main()
{
	string str;
	getline(cin,str);
	cout << str << endl;
	return 0;
}


cin.getline() 与 getline() 类似,但是因为 cin.getline() 的输出是char*,getline() 的输出是 string,所以 cin.getline() 属于 istream 流,而 getline() 属于 string 流,二者是不一样的函数

参考链接
https://www.cnblogs.com/mini-coconut/p/9041925.html
https://www.cnblogs.com/flatfoosie/archive/2010/12/22/1914055.html