我很抱歉,但我找不到更好的标题。我正在关注Stroustrup的编程:使用C ++的原理和实践。这个示例代码引起了我的注意。我的问题是,cin如何识别一个单词中的两种不同类型,如200.40i(200.40 double和i char)?我的意思是,它不应该期待至少一个空格分隔的输入吗?
int main()
{
constexpr double cm_per_inch = 2.54;
double length = 1;
char unit = 0;
cout << "Please enter a length followed by a unit (c or i):\n";
cin >> length >> unit;
if (unit == 'i')
cout << length << "in == " << cm_per_inch*length << "cm\n";
else
cout << length << "cm == " << length/cm_per_inch << "in\n";
}
如果我只是运行程序并输入:200.40i工作正常,同样适用于:200.40 i和for:200.40 \ n i。
答案 0 :(得分:2)
这是对格式化输入提取运算符a.k.a。>>
的内部工作的粗略过度简化,用于解释您正在观察的输入行为。这就是>>
的工作原理:
第1步:跳过输入流中的任何空格。
步骤2:将输入流的下一部分转换为任何数据类型>>
。从输入流中提取 仅 已转换的输入。
为每个>>
运算符执行这两个步骤。正如我所说,这是过于简单化。还有其他事情正在发生,例如异常处理的岗哨对象,这里无关紧要。
重要的是>>
没有&#34;停止&#34;当它看到任何被提取的空格时。这是>>
在介绍性C ++文本中经常被解释的方式,但它并不完全正确。 >>
一旦完成提取所提取的内容就会停止, 不 会提取其后的内容。现在,关注&#34;无论提取什么&#34;你经常会有额外的空格。没关系。格式化的输入提取运算符将在该点停止。但重要的是它将 不 提取空白。这将由 后续 >>
提取(如果有的话)处理。
它不一定是空白。它可能是任何不再被解析的东西。所以,在你的情况下:
cin >> length >> unit;
length
是double
。 unit
是char
。您的意见是:
200.40i
第一个>>
仅提取&#34; 200.40&#34;。字符i
可能不属于double
值,因此提取会在此时停止,i
不 < / strong>提取。所以第一个>>
唯一能够摆脱它的东西。然后,第二个>>
提取孤独的&#34; i&#34;字符。
格式化的提取运算符,出于所有实际目的,始终uses peek() to look at the next character in the input stream,以决定是否将其作为从输入流中提取的任何内容的一部分进行提取。如果它看起来不错,那就会被吞噬。
现在,如果有一些空白:
200.40 i
第一个>>
将double
取出,就像之前一样,然后停止,但它不会提取空间。 2nd >>
跳过空白作为其第34步&#34;的一部分,然后提取char
。
所以,你看,>>
格式化的提取操作符在 之后丢弃空白而不是 ,它提取它提取的内容,但 之前< / EM> 强>
其他几点说明:
如果>>
提取到std::string
,则会提取除空格之外的任何内容,因此此处停止提取的唯一内容是尾随空格。但是尾随空格本身仍然没有被提取,但只能由下一个>>
运算符提取。
如果在这种情况下,>>
提取到孤独的char
,则此char
只能容纳一个字符,以便所有这些&#39}在那种情况下,我将被提取出来。
答案 1 :(得分:0)
http://www.learncpp.com/cpp-tutorial/5-10-stdcin-extraction-and-dealing-with-invalid-text-input/
使用提取运算符时,会发生以下过程:
因此,在您的示例中,200.40
将被提取并转换为double。由于输入缓冲区仍然有i
,它将被提取到char中。
答案 2 :(得分:0)
为了理解它是如何工作的,你需要对面向对象编程有一点了解。
在C ++中,cin
是一个对象。
但你可能会问,什么是对象?
基本上,对象是可以使用各种运算符操作的数据结构:
例如+
-
*
/
%
<<
>>
等
C ++中的两种类型的对象是:built-in type
和user-defined type
。
无论你是否知道,你都在C ++中一直使用对象!
例如,您的变量length
是内置类型double
的对象。
现在你可以用length
做什么?
它支持+
-
*
/
等等。
这是一种非常直观的类型。
那么cin
呢?
cin
是用户定义类型istream
的对象。
我们知道它支持运算符>>
,它被称为按位右移运算符。
此运算符(在cin
的情况下)获取给定的输入数据并将其(将其移动)放入变量中。
此运算符的一个功能是您可以链接多个变量:
例如cin >> variable1 >> variable2 >> variable3;
就像在double类型的对象中使用运算符+
一样:
例如length + 1 + 2 + 3;
但链中的每个变量必须由>>
运算符分隔。