C++ cin:读取键盘输入的数据

cin 可以用于读取键盘输入的数据。

目前为止,读者只可以使用必要的起始值初始化变量,而无须让用户输入自己的数据。这些类型的程序仅限于使用一组启动信息执行任务。如果决定要更改任何变量的初始值,则必须对该程序进行修改并重新编译。

实际上,大多数程序都需要获得某些值,然后将它们分配给变量。这意味着即使用户希望使用不同的信息来多次运行程序,也不需要对它进行修改。例如,计算圆面积的程序可能会要求用户输入圆的半径。当完成圆面积的计算和打印时,程序可以再次运行,并且可以输入不同的半径。

正如 C++ 提供了 cout 对象来产生控制台输出一样,它还提供了一个名为 cin 的对象用于读取控制台的输入。下面的程序演示了如何使用 cin 来读取用户输入的值:
// This program calculates and displays the area of a rectangle.
#include <iostream>
using namespace std;

int main()
{
    int length, width, area;
    cout << "This program calculates the area of a rectangle.\n";
    // Have the user input the rectangle's length and width
    cout << "What is the length of the rectangle? ";
    cin >> length;
    cout << "What is the width of the rectangle? ";\
    cin >> width;
    // Compute and display the area area = length * width;
    cout << "The area of the rectangle is " << area << endl;
    return 0;
}
程序输出结果:

This program calculates the area of a rectangle.
What is the length of the rectangle? 10
What is the width of the rectangle? 20
The area of the rectangle is 200.

请注意,在第 2 行中有一个包含 iostream 文件的 #include 语句。该文件必须包含在使用 cin 的任何程序中。

该程序并不仅限于计算一个矩形的面积,而是可以用于计算任何矩形的面积。length 和 width 变量中存储的值,在程序运行时由用户输入。

cout << "What is the length of the rectangle?
cin >> length;

在代码中,cout 用于显示问题“What is the length of the rectangle?”,这称为提示,它让用户明白这里需要输入,并提示必须输入什么信息。当使用 cin 来从用户获取输入时,它应该始终在一个提示之前。

然后,使用 cin 从键盘读取一个值。>> 符号是流提取运算符,它从输入流中提取字符,从而可以在程序中使用。更具体地说,流提取运算符从左侧的流对象获取字符,并将其存储在其右侧出现的变量中。在该行示例中,由 cin 读取来自 cin 对象的字符并将它存储到 length 变量中。

从用户收集输入通常有两个步骤:
  1. 使用 cout 在屏幕上显示提示。
  2. 使用 cin 从键盘读取值。

提示应该向用户提出一个问题,或者告诉用户输入一个特定的值。例如,上面程序的代码显示了以下提示:

What is the length of the rectangle?

这就是告诉用户应输入矩形的长度。显示提示之后,程序使用 cin 从键盘读取值并将其存储在 length 变量中。

请注意,<< 和 >> 运算符看起来像是在指示数据流动的方向。将它们视为箭头将有助于理解。在使用 cout 的语句中,<< 运算符总是指向 cout,如下所示,表示数据是从变量或常数流动到 cout对象:

cout << "What is the length of the rectangle? ";
cout <- "What is the length of the rectangle? ";

在使用 cin 的语句中,>> 运算符总是指向接收值的变量,表示数据是从 cin 对象流动到变量:

cin >> length;
cin —> length;

cin 对象导致程序等待,直到在键盘上输入数据按回车键。在 cin 接收到输入之前,不会有其他的行被执行。

当用户从键盘输入字符时,它们暂时放置在称为输入缓冲区或键盘缓冲区的内存区域中。当 cin 读取它们时,会自动将它们转换为要存储输入数据的变量的数据类型。

例如,如果用户键入 10,它将被读取为字符 '1' 和 '0',但是 cin 足够聪明,知道在存储到 length 变量之前必须将其转换为 int 值 10。但是,如果用户输入像 10.7 这样的浮点数,则会出现问题。cin 知道这样的值不能存储在整数变量中,所以当它读到小数点时即停止读取,在输入缓冲区中保留小数点和其余数字。当下一个值被读入时,这可能会导致出现问题。下面的程序演示了这个问题:
//This program illustrates what can happen when a
// floating-point number is entered for an integer variable.
#include <iostream>
using namespace std;

int main()
{
    int intNumber;
    double floatNumber;
    cout << "Input a number. ";
    cin >> intNumber;
    cout << "Input a second number.\n";
    cin >> floatNumber;
    cout << "You entered: " << intNumber << " and " << floatNumber << endl;
    return 0;
}
程序输出结果:

Input a number . 12.3
Input a second number. You entered: 12 and 0.3

现在来分析一下这个程序。当提示输入第一个数字时,用户从键盘输入 12.3。但是,因为 cin 正在读取的值将存入 intNumber 这个整型变量中,所以,当它遇到小数点,就会停止读取,并且将 12 存储到 intNumber 变量中。当第二个 cin 语句需要读取一个值存入 floatNumber 变量中时,它发现在输入缓冲区中已经有一个值,也就是从用户第一次输入中遗留下来的 ".3",于是就不必等待用户输入第二个数字,而是读入 ".3" 并将它存储到 floatNumber 变量中。

后面将介绍如何防止这样的事情发生,在此只是为了说明,需要为用户提供清晰的提示。

输入多个值

可以使用 cin 一次输入多个值:
// This program calculates and displays the area of a rectangle.
#include <iostream>
using namespace std;

int main()
{
    int length, width, area;
    cout << "This program calculates the area of a rectangle. \n";
    //Have the user input the rectangle1s length and width
    cout << "Enter the length and width of the rectangle "
    cout << "separated by a space. \n";
    cin >> length >> width;
    // Compute and display the area
    area = length * width;
    cout << "The area of the rectangle is " << area << endl;
    return 0;
}
程序输出结果:

This program calculates the area of a rectangle.
Enter the length and width of the rectangle separated by a space.
10 20

第 14 行等待用户输入两个值。第一个被赋值给 length,第二个则赋值给 width:

cin >> length >> width;

在示例输出中,用户输入 10 和 20,因此 10 存储在 length 中,而 20 存储在 width 中。注意,用户在输入数字时要用空格分隔数字。这样 cin 才能知道每个数字的开始和结束位置。在每个数字之间输入多少空格并不重要,需要注意的是,在最后一个数字输入之后,必须按回车键。

还可以使用单个 cin 语句读取不同数据类型的多个值。下面的程序显示了这种用法:
// This program demonstrates how cin can read multiple values
// of different data types.
#include <iostream>
using namespace std;

int main()
{
    int whole;
    double fractional;
    char letter;
    cout << "Enter an integer, a double, and a character: ";
    cin >> whole >> fractional >> letter;
    cout << "whole: " << whole << endl;
    cout << "fractional: " << fractional << endl;
    cout << "letter: " << letter << endl;
    return 0;
}
程序输出结果:

Enter an integer, a double, and a character: 4 5.7 b
whole: 4
fractional: 5.7
letter: b

在上述示例输出和图 1 均可见,这些值将按照输入的顺序存储到相应的变量中。

输入的值将按顺序存储到相应的变量中
图 1 输入的值将按顺序存储到相应的变量中

但是如果用户像以下示例一样,以错误的顺序输入了值,那么结果会怎么样呢?程序输出结果为:

Enter an integer, a double, and a character: 5.7 4 b
whole: 5
fractional: 0.7
letter: 4

因为没有按照指定的顺序输入数据,所以每个变量存储的值被完全打乱了。图 2 已清楚说明究竟发生了什么。

未按顺序输入值将造成变量存储的值完全乱套
图 2 未按顺序输入值将造成变量存储的值完全乱套

cin 语句读取 5 存入 int 类型的 whole 变量,读取 ".7" 存入 double 类型的 fractional 变量,读取 4 存入 char 类型的 letter 变量。字符 b 则遗留在输入缓冲区中。所以,为了使程序正常工作,用户按照程序期望接收的顺序输入数据值是非常重要的,并且在需要整数时不能输入浮点数。