我运行了这段代码
char c;
cin >> c;
cout << c;
cin >> c;
cout << c;
并且我在控制台中输入了
ab
,然后按下回车。接下来的一行输出显示了ab
。但是我不明白它是如何工作的。在按下回车之前,程序没有读取任何内容,对吗?按下回车后,它先读取a
,将其保存到char c
中,然后再次读取char c
,并将a
写入控制台。这还好。但是它如何在第二行读取b
呢?第二行并没有b
。cin
是标准输入流。理解C++的I/O,深入了解其数据流模型非常重要。
默认情况下,执行cin >> x
意味着:
从当前的流指针位置开始,跳过可能存在的任何空白字符,然后尝试尽可能长地读取直到获取一个有效的表示
x
的值。
让我们暂时忽略输入是来自键盘这个事实。在程序开始时,流的内容为a b LINEFEED
。接着执行cin >> c
,它将从输入中读取第一个字符a
,并将其填充到变量c
中,此时读取停止。现在,cin
流的内容为b LINEFEED
。接着把变量c
写入标准输出流。
接下来再次执行cin >> c
,所以又会读取一个字符(这次是b
)。同样,只需读取一个字符即可停止读取,并且流的内容现在为LINEFEED
。接着输出b
到标准输出流。
标准输入和标准输出流通常被绑定到控制台,但这并不影响它们的内部工作方式。cin
并不会因为在屏幕上出现一些输出就“忘记”其中的内容。特别是,cin
读取的是键盘输入,而不是“控制台上的字符”。只是碰巧按下键盘的键既会回显在控制台上,也会传递给cin
。
因此,程序在输出字符a
之后对cin
流的内容没有任何影响。
cin和cout是带缓冲的流。当您按下回车键时,'a'和'b'都会进入输入缓冲区。'>>'运算符从该缓冲区读取(在您的情况下一次读取一个字符)。'<<'写入输出缓冲区。唯一让您惊讶的事情是,您在输出上看到“ab”而没有打印“\ n”(后者应刷新输出缓冲区内容到终端)。
简而言之,cin和cout都是缓冲区。输入和输出运算符与这些缓冲区一起工作。换行符号启动数据传输,将真实输入传输到输入缓冲区,并将输出缓冲区传输到真实输出。
关于I/O还有更多可以学习的东西。
cin是一个阻塞输入。无论从键盘输入什么都会被存储在缓冲区中。当您按下回车时,系统将缓冲区传递给应用程序代码(std::cin代码)。 运算符 >> 将决定从该缓冲区读取多少内容——一个字符、字符串、整数、浮点数等,这取决于操作数的类型。
cin
有一个针对数据类型 char
的重载,只从输入流中获取1个字符,因此您的程序基本上是这样的:
char c;
cin >> c; // reads 'a' from the input stream (input stream contains 'ab\n')
cout << c; // prints 'a'
cin >> c; // changes c to 'b' (reads 'b')
cout << c; // prints 'b'
char
类型,执行cin >> c;
两次,这意味着当有两个char
可用时,它将读取两个字符。因此,它首先读取'a'
,然后通过cout << c;
打印它,接着读取'b'
并打印它。因此,预期会打印出'a'
和'b'
(例如,ab
)。 - James Adkisonb
时,它位于第二行。如何返回到第一行? - Pavelmain
和using namespace std;
(或者你觉得 MCVE 还缺少什么)?它们与手头的问题无关。 - Angew is no longer proud of SOab
(在一行上),然后输出是ab
(在第二行上),但根据 OP 的评论,听起来他们很困惑,或者我没有理解输入和输出。人们经常发布与他们实际使用的代码不符的代码。 - James Adkison