连续cin输入如何在C ++中工作

时间:2018-04-13 02:58:41

标签: c++

我很抱歉,但我找不到更好的标题。我正在关注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。

3 个答案:

答案 0 :(得分:2)

这是对格式化输入提取运算符a.k.a。>>的内部工作的粗略过度简化,用于解释您正在观察的输入行为。这就是>>的工作原理:

第1步:跳过输入流中的任何空格。

步骤2:将输入流的下一部分转换为任何数据类型>>。从输入流中提取 已转换的输入。

为每个>>运算符执行这两个步骤。正如我所说,这是过于简单化。还有其他事情正在发生,例如异常处理的岗哨对象,这里无关紧要。

重要的是>>没有&#34;停止&#34;当它看到任何被提取的空格时。这是>>在介绍性C ++文本中经常被解释的方式,但它并不完全正确。 >>一旦完成提取所提取的内容就会停止, 会提取其后的内容。现在,关注&#34;无论提取什么&#34;你经常会有额外的空格。没关系。格式化的输入提取运算符将在该点停止。但重要的是它将 提取空白。这将由 后续 >>提取(如果有的话)处理。

它不一定是空白。它可能是任何不再被解析的东西。所以,在你的情况下:

cin >> length >> unit;

lengthdoubleunitchar。您的意见是:

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/

使用提取运算符时,会发生以下过​​程:

  1. 如果输入缓冲区中已有数据,则该数据用于提取。
  2. 如果输入缓冲区不包含数据,则要求用户输入要提取的数据(大多数情况下都是这种情况)。当用户按Enter键时,'\ n'字符将被放入输入缓冲区。
  3. 运营商GT;&GT;从输入缓冲区中尽可能多地从变量中提取数据(忽略任何前导空白字符,例如空格,制表符或'\ n')。
  4. 任何无法提取的数据都会留在输入缓冲区中以供下次提取。
  5. 因此,在您的示例中,200.40将被提取并转换为double。由于输入缓冲区仍然有i,它将被提取到char中。

答案 2 :(得分:0)

为了理解它是如何工作的,你需要对面向对象编程有一点了解。
在C ++中,cin是一个对象。

但你可能会问,什么是对象?
基本上,对象是可以使用各种运算符操作的数据结构:
例如+ - * / % << >>
C ++中的两种类型的对象是:built-in typeuser-defined type

无论你是否知道,你都在C ++中一直使用对象!
例如,您的变量length是内置类型double的对象。

现在你可以用length做什么?
它支持+ - * /等等。
这是一种非常直观的类型。

那么cin呢?
cin是用户定义类型istream的对象。
我们知道它支持运算符>>,它被称为按位右移运算符。
此运算符(在cin的情况下)获取给定的输入数据并将其(将其移动)放入变量中。

此运算符的一个功能是您可以链接多个变量:
例如cin >> variable1 >> variable2 >> variable3;
就像在double类型的对象中使用运算符+一样:
例如length + 1 + 2 + 3;

但链中的每个变量必须由>>运算符分隔。