8.11 获取用户输入
目前为止,我们写的程序都是可预见的,它们每次运行时都做相同的事情。然而大多数时候我们需要程序能从用户那得到输入并随之做出反应。
有很多种方式可以得到输入,包括键盘输入,鼠标移动和按钮点击,此外还有更特别的机制,例如声控和视网膜扫描。本文我们只考虑键盘输入。
在头文件iostream.h中,C++定义了一个cin对象来处理输入,就像用cout对象处理输出一样。从用户那得到一个整型值可以这么写:
int x;
cout >> x;
>>操作符使得程序停止执行,等待用户输入。如果用户输入了有效值,程序会将它转换成整型值并存放在x中。
如果用户输入的不是整型,C++不会报告一个错误。相反,它把一些无意义的值存在x中并继续执行。
幸运的是,有一种方法可以检查输入语句是否成功。我们可以在cin上调用good函数来检验所谓的流状态。good方法返回一个布尔值:如果为真,则说明上一次的输入语句成功了。否则,我们知道之前的一些操作失败了,而且接下来的操作也会失败。
因此,从用户那得到输入看起来会像这样:
int main()
{
int x;
// 提示用户输入
cout << "Enter an integer: ";
// 获取输入
cin >> x;
//检查输入语句是否成功
if(cin.good == flase) {
cout << "That was not an integer." << endl;
return -1;
}
//打印从用户处得到的值
cout << x << endl;
return 0;
}
cin也可以用于输入一个apstring:
apstring name;
cout << "What's your name? ";
cin >> name;
cout << name <<endl;
遗憾的是,这条语句只得到了输入的第一个单词,而把剩下的输入留给了下一条输入语句。所以,如果你运行这段程序并打下你的全名,它将只输出你的第一个名字。
正因为这些问题(无法处理错误和可笑的行为),我完全避免使用>>操作符,除非我是从确定无误的源中读取数据。
作为替代方法,我在aspstring中使用了一个getline方法。
apstring name;
cout << "What is your name? ";
getline(cin, name);
cout << name << endl;
getline的第一个参数是cin,它是输入的来源。第二个参数是spstring的名字,用来存储结果。
getline读入整行输入直到用户敲打Return或Enter键。这对于输入包含空格的字符串来说是很有用的。
事实上,getline对于获取任何输入通常都有效。例如,若你想让用户输入一个整数,你可以输入一个字符串然后检查它是否是一个有效整数。如果是,你能把它转换成一个整数值。否则,你能输出一个错误信息并让用户再次输入。
为了将字符串转换成整数,你可以使用atoi函数,它定义在在头文件stdlib.h中。我们会在15.4节中讨论到它。