cin是如何工作的?

9

我运行了这段代码

char c;
cin >> c;
cout << c;
cin >> c;
cout << c;

并且我在控制台中输入了ab,然后按下回车。接下来的一行输出显示了ab。但是我不明白它是如何工作的。在按下回车之前,程序没有读取任何内容,对吗?按下回车后,它先读取a,将其保存到char c中,然后再次读取char c,并将a写入控制台。这还好。但是它如何在第二行读取b呢?第二行并没有b

2
“'c'” 是一个 char 类型,执行 cin >> c; 两次,这意味着当有两个 char 可用时,它将读取两个字符。因此,它首先读取 'a',然后通过 cout << c; 打印它,接着读取 'b' 并打印它。因此,预期会打印出 'a''b'(例如,ab)。 - James Adkison
@JamesAdkison 但是当程序写入 b 时,它位于第二行。如何返回到第一行? - Pavel
不太确定cin的内部工作原理,但它确实期望在输入完成时按下新行(Enter)键。因此,它读取的可能是"a\n",但它只在第一个cout中显示了a。同样,对于"b\n"也是如此,但它再次显示了b。Cin会吞掉那个'\n',即换行符。好的阅读材料:http://en.cppreference.com/w/cpp/io/cin和http://en.cppreference.com/w/cpp/io/basic_istream/ignore。第二个链接特别提供了一个示例,说明如何忽略N个字符或直到预期的'\n'字符。编辑:对于您在此处的评论,您按下了回车键,所以它向下移动了 :) - SenselessCoder
@Pavel 如果您仍有疑问,请提供一个“最小、完整和可验证的示例”(http://stackoverflow.com/help/mcve)。此外,如果您能够展示输入内容的确切样子以及您所看到的输出结果(即,[编辑](http://stackoverflow.com/posts/36914079/edit)您的问题以添加这些细节),那就更好了。 - James Adkison
1
@JamesAdkison 我认为从当前问题中的代码中,概念已经很清晰了。为什么要强制用户添加 mainusing namespace std; (或者你觉得 MCVE 还缺少什么)?它们与手头的问题无关。 - Angew is no longer proud of SO
@Angew 是的,代码非常清晰,但最好明确显示他们的输入和输出是什么。对我来说,听起来输入是 ab(在一行上),然后输出是 ab(在第二行上),但根据 OP 的评论,听起来他们很困惑,或者我没有理解输入和输出。人们经常发布与他们实际使用的代码不符的代码。 - James Adkison
4个回答

20

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流的内容没有任何影响。


2

cin和cout是带缓冲的流。当您按下回车键时,'a'和'b'都会进入输入缓冲区。'>>'运算符从该缓冲区读取(在您的情况下一次读取一个字符)。'<<'写入输出缓冲区。唯一让您惊讶的事情是,您在输出上看到“ab”而没有打印“\ n”(后者应刷新输出缓冲区内容到终端)。

简而言之,cin和cout都是缓冲区。输入和输出运算符与这些缓冲区一起工作。换行符号启动数据传输,将真实输入传输到输入缓冲区,并将输出缓冲区传输到真实输出。

关于I/O还有更多可以学习的东西。


2

cin是一个阻塞输入。无论从键盘输入什么都会被存储在缓冲区中。当您按下回车时,系统将缓冲区传递给应用程序代码(std::cin代码)。 运算符 >> 将决定从该缓冲区读取多少内容——一个字符、字符串、整数、浮点数等,这取决于操作数的类型。


0
基本上,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'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接