重新认识cin、cout
C++语言通过一个全面的标准库来提供IO机制(即iostream库),包含两个基础类型istream和osteam,表示输入流、输出流。流就是不断的字符序列,从IO设备读进来或者写出到IO设备。也就是说,程序运行时的窗口(IO设备)就与输入输出流的对象联系起来。
标准的输入输出对象有4个:istream类型的cin,ostream类型的cout、cerr(输出警告和错误信息 与return
-1连用)、clog(输出程序运行的一般性信息)。
cin
cin是一个输入流的对象,cin会将数据从程序正在运行的窗口(IO设备其实是键盘)读入,这时的读入数据用>>(输入运算符),>>是一个双目运算符,左边是istream类型的对象,右侧可以是一个变量对象,运算符的结果返回其左侧运算对象(即cin)作为计算结果。cin使用的是行缓冲机制,当输入接收到回车的时候就会进行数据的刷新,cin主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。
cout
cout是一个输出流对象,会将buffer中的数据写到窗口上,使用<<(输出运算符),右侧的运算对象是要打印的值。cout可以连续打印多个值,并最终返回左侧的ostream对象。endl是操纵符,意思是结束当前行,并将与窗口关联的buffer中的内容刷新到设备中。
buffer-输入缓冲区
当我们从键盘输入字符串的时候需要敲一下回车键才能够将这个字符串送入到缓冲区中,那么敲入的这个回车键会被转换为一个换行符\n,这个换行符\n也会被存储在cin的缓冲区中并且被当成一个字符来计算!比如我们在键盘上敲下了123456这个字符串,然后敲一下回车键将这个字符串送入了缓冲区中,那么此时缓冲区中的字节个数是7 ,而不是6。
cin读取数据也是从缓冲区中获取数据,缓冲区为空时,cin的成员函数会阻塞等待键盘键入数据的到来,一旦缓冲区中有数据,就触发cin的成员函数去读取数据。 也就是说,缓冲区还有数据未读的情况下,窗口不会让你键入数据。
输入的行缓冲机制:当键盘上输入换行符时,才进行输入操作。键盘上的数先是存放在缓冲区内,当遇到换行符时(换行符也被存在缓冲区中)进行cin>>a操作,若键盘输入的数与a不同类型,此时>>运算符返回的结果是cin对象但是它的状态已经是false(这种情况在遇到eof也会出现),接下来再进行cin>>b时,会发现没有读进去值。此时需要刷新缓冲区,将缓冲区的残余数据销毁。
首先,使用clear()进行条件状态的复位,经实验验证,在cin状态出错之后,无法进行下一步的>>操作,在cin.clear()之后,cin状态变成true之后,可以将缓冲区剩下的赋给b。若缓冲区残余数值与b不是一个类型,需要清空输入缓冲区,使用
istream &ignore( streamsize num=1, int delim=EOF );
跳过输入流中n个字符,或在遇到指定的终止字符时提前结束(此时跳过包括终止字符在内的若干字符)。第一个参数可以设置很大1024,第二个通常是‘'\n',功能就是用来清除以回车结束的输入缓冲区的内容,消除上一次输入对下一次输入的影响。接着可以重新从键盘输入数据并进行后续的>>操作
也可以
`cin.sync();` 这个是用来清空cin缓冲区里面未读取的信息。
这个要注意要先将cin的状态置为true之后sync才有作用,也就是先clear() 再sync()才会清空缓冲区。可以用cin.fail()观察cin 的状态。注:不一样的编译器对sync()方法表现不一样,VS2017下没有对缓冲区进行清除,所以还是用.ignore()方法合适。
转自:
https://blog.csdn.net/codedoctor/article/details/78886169
https://blog.csdn.net/qq_28427119/article/details/79281348
输出缓冲区
<<操作符将要打印的数据放在缓冲区内,什么时候才从缓冲区刷新到IO设备(程序运行窗口上)是个问题。endl是一个操纵符,可以强制刷新缓冲区,可以刷新缓冲区的情况还有:
1、缓冲区满时
2、执行flush语句
3、执行endl语句
4、关闭文件
cin cout 与buffer
键盘--------①-----------buffer--------②----------变量 cin在②起作用
数值--------①-----------buffer--------②----------窗口 cout在①起作用