C++中的输入

  • C++中使用cin对象来获取用户的输入

cin是一个标准输入流对象,即是istream类的对象

cin是全局变量

cin对象”连接”到标准输入设备(一般是用户的键盘),用来存储IO流中的输入的数据(保存在cin的输入流缓冲区中)

1
2
int i;
cin >> i;

cin >> i在执行时

  • 系统从cin的输入流缓冲区中获取数据

    • 如果cin的输入流缓冲区中没有数据,则等待用户在控制台输入数据,然后按下回车,将数据送入cin的输入流缓冲区

      输入的数据只有在缓冲区才能被读取

      空格、tab、换行符,也都是数据,分别是' ' '\t' '\n'

      键盘上的回车键对应的是输入'\r',输入后,会将数据送入缓冲区,并且'\r'变成'\n'保存在缓冲区数据的最后面,作为分隔符

  • 然后将cin输入流缓冲区的数据赋值给i

cin输入流缓冲区保存数据的形式本质上是二进制,根据上下文(被赋值对象的类型),将数据以被赋值对象的类型赋值给被赋值对象

比如

1
2
char a;
cin >> a;

如果在控制台中输入65cin输入流缓冲区的数据赋值给a的时候,按照a的类型char,赋值给a的数据是'A'

这跟从控制台中输入A的作用是一样的,因为它们的数据一样,只是上下文不同,含义不同

”流“

像是一个管道,或者说队列

先流入的先流出,后流入的后流出

在向输入流输入数据的时候,数据流入到输入流,先输入的在前面,后输入的在后面

在向输入流获取数据的时候,数据流出输入流,先获取前面的数据,再获取后面的数据

cin的输入流缓冲区中保存用户输入的所有数据,根据指令将数据从前向后依次赋值给对象,若缓冲区为空,则从控制台中获取新输入的数据到输入流缓冲区

所以并不是需要输入一个数据的时候输入一个数据,而是可以一次性将多个数据输入,在需要的时候从缓冲区取

根据被赋值对象类型的不同、操作方式不同,cin从缓冲区读取数据的方式也不同

比如:

在控制台输入1 2 3 4 5 6 7 ,每个数字之间有空格

输入之后要按下回车,将数据送入到标准输入缓冲区,cin的输入缓冲区变成了1 2 3 4 5 6 7'\n'

如果执行

1
2
int i;
cin >> i;

因为i是一个整形,则系统会将cin输入流1 2 3 4 5 6 7'\n'中分隔符之前的数据作为整形赋值给i

正如上面所说,数据并不是按照整形或者字符存储在缓冲区的,而是二进制,这里这样表示是为了直观

此时以空格' '、tab'\t'和换行符'\n'作为分隔符,遇到分隔符就停止获取,此时是将1赋值给icin输入流缓冲区中剩下的数据是2 3 4 5 6 7\n

此时cin的输入流缓冲区在获取数据的时候,空格' '、tab'\t'、换行符'\n'等是作为分隔符的。

并且此时如果分隔符在有效数据之前,会自动将分隔符忽略掉,直到获取的数据是有效数据而不是分隔符

比如

1
2
char a;
cin >> a;

如果输入" A"(A之前很多空格),A是才有效数据,A之前的空格是分隔符,在从cin的输入流缓冲区获取数据的时候,会自动忽略A之前的分隔符空格,只获取有效数据A

截屏2023-03-15 16.41.29

书接上回,如果再执行

1
2
string a;
cin >> a;

a中只会获取"2",因为2后面的空格是分隔符

我们下面不用这个方式进行演示,假设上面这行代码没有写入

如果此时再向控制台输入hello world并按下回车,输入的数据会送入到cin的输入流缓冲区,现在cin的输入流缓冲区的数据是2 3 4 5 6 7'\n'hello world\n'

如果再执行

1
2
3
4
string x;
getline(cin,x);
//getline是C++标准库函数,分为两种形式(重载),只知道此处的作用是可以获取cin缓冲区中一行数据(字符串)赋值给字符串x,也就是可以获取换行符之前的所以数据,包括空格
//getline是从cin缓冲区中获取制定类型的数据,类似的还有getchar,getchar等,这样就好理解了

此时空格' '就不作为分隔符了,因为空格在这里作为一个字符' ',分隔符是换行符'\n',指令getline(cin,x)会将cin输入流缓冲区中分隔符之前的所有数据赋值给x,x中的数据是"2 3 4 5 6 7"

cin输入流缓冲区剩下的是hello world\n'

如果再执行

1
2
string y;
getline(cin,y);

y中的数据是hello worldcin输入数据流中没有数据了