基本输入/输出
到目前为止,前面章节的示例程序与用户的交互非常少,甚至没有。使用标准输入输出库,我们将能够与用户交互,在屏幕上打印消息并从键盘获取用户的输入。
C++ 使用一个方便的抽象概念,称为
流,来执行在屏幕或键盘等顺序介质中的输入和输出操作。流是一个对象,程序可以向其中插入或从中提取字符。我们实际上不需要关心与流关联的物理介质的许多规范 - 我们只需要知道它将按顺序接受或提供字符。
标准 C++ 库包含头文件
iostream,其中声明了标准输入和输出流对象。
标准输出 (cout)
默认情况下,程序的标准输出是屏幕,用于访问它的 C++ 流对象是
、cout.
、cout与
插入运算符一起使用,该运算符写成
<<(两个“小于”符号)。
1 2 3
|
cout << "Output sentence"; // prints Output sentence on screen
cout << 120; // prints number 120 on screen
cout << x; // prints the content of x on screen
|
要放回的字符的
<<运算符将其后面的数据插入到它前面的流中。在上面的例子中,它插入了常量字符串
输出语句,数值常量
120和变量
x到标准输出流
、cout。请注意,第一条指令中的句子用双引号 (
") 括起来,因为它是一个常量字符串。每当我们想使用常量字符串时,我们必须用双引号 (
") 括起来,以便将它们与变量名清楚地区分开来。例如,这两个句子有非常不同的结果
1 2
|
cout << "Hello"; // prints Hello
cout << Hello; // prints the content of Hello variable
|
插入运算符 (
<<) 可以在单个语句中使用多次
1
|
cout << "Hello, " << "I am " << "a C++ statement";
|
最后一条语句将在屏幕上打印消息
Hello, I am a C++ statement。重复使用插入运算符 (
<<) 的实用性在于,当我们想要打印变量和常量或多个变量的组合时。
1
|
cout << "Hello, I am " << age << " years old and my zipcode is " << zipcode;
|
如果我们假设
age变量包含值
24和
zipcode变量包含
90064则前一个语句的输出将是
1
|
Hello, I am 24 years old and my zipcode is 90064
|
重要的是要注意
、cout不会在其输出后添加换行符,除非我们明确指示,因此,以下语句
1 2
|
cout << "This is a sentence.";
cout << "This is another sentence.";
|
将在屏幕上一个接一个地显示,它们之间没有任何换行符
This is a sentence.This is another sentence.
即使我们将它们写成两个不同的插入到
、cout。为了在输出中执行换行,我们必须显式地将一个新行字符插入到
、cout。在 C++ 中,可以将新行字符指定为
\n(反斜杠,n)
1 2
|
cout << "First sentence.\n";
cout << "Second sentence.\nThird sentence.";
|
这将产生以下输出
First sentence.
Second sentence.
Third sentence.
此外,要添加新行,您还可以使用
endl操纵器。例如
1 2
|
cout << "First sentence." << endl;
cout << "Second sentence." << endl;
|
将打印出
First sentence.
Second sentence.
要放回的字符的
endl操纵器会产生一个换行符,与插入
'\n'一样,但当它与缓冲流一起使用时,它还具有一个额外的行为:缓冲区被刷新。无论如何,
、cout在大多数情况下将是一个非缓冲流,因此您通常可以使用
\n转义字符和
endl操纵器来指定新行,而其行为没有任何差异。
标准输入 (cin)。
标准输入设备通常是键盘。在 C++ 中处理标准输入是通过将重载的提取运算符 (
>>) 应用于
cin流来完成的。运算符后面必须跟变量,该变量将存储要从流中提取的数据。例如
第一条语句声明一个类型为
int的变量,名为
age,第二条语句等待来自
cin(键盘) 的输入,以便将其存储在此整数变量中。
cin只有在按下
RETURN键后才能处理来自键盘的输入。因此,即使你请求一个字符,来自
cin的提取也不会处理输入,直到用户在引入字符后按下
RETURN。
您必须始终考虑正在使用的变量类型作为与
cin提取的容器。如果你请求一个整数,你将得到一个整数,如果你请求一个字符,你将得到一个字符,如果你请求一个字符串,你将得到一个字符串。
|
// i/o example
#include <iostream>
using namespace std;
int main ()
{
int i;
cout << "Please enter an integer value: ";
cin >> i;
cout << "The value you entered is " << i;
cout << " and its double is " << i*2 << ".\n";
return 0;
}
|
Please enter an integer value: 702
The value you entered is 702 and its double is 1404. |
程序的用户可能是导致错误的因素之一,即使在使用
cin(就像我们刚才看到的那个) 的最简单的程序中也是如此。因为如果你请求一个整数值,而用户引入一个名称(通常是一个字符串),结果可能会导致你的程序运行错误,因为它不是我们期望用户提供的。因此,当你使用
cin提取提供的数据输入时,你必须相信你的程序的用户会合作,并且在请求整数值时,他/她不会引入他/她的姓名或类似的内容。稍后,当我们看到
stringstream类时,我们将看到一个可能的解决方案,可以解决由这种类型的用户输入引起的错误。
您还可以使用 cin 从用户请求多个数据输入
等价于
在这两种情况下,用户必须提供两个数据,一个用于变量
a,另一个用于变量
和 bb,它们可以被任何有效的空白分隔符分隔:空格、制表符或换行符。
cin 和字符串
我们可以使用
cin来获取带有提取运算符 (
>>) 的字符串,就像我们使用基本数据类型变量一样
但是,正如所说,
cin提取在找到任何空白字符时立即停止读取,因此在这种情况下,我们将能够为每个提取只得到一个单词。这种行为可能符合我们的需求,也可能不符合;例如,如果我们想从用户那里得到一个句子,那么这个提取操作将没有用处。
为了获得整行,我们可以使用函数
getline,这是使用
cin:
|
// cin with strings
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string mystr;
cout << "What's your name? ";
getline (cin, mystr);
cout << "Hello " << mystr << ".\n";
cout << "What is your favorite team? ";
getline (cin, mystr);
cout << "I like " << mystr << " too!\n";
return 0;
}
|
What's your name? Juan Soulie
Hello Juan Soulie.
What is your favorite team? The Isotopes
I like The Isotopes too! |
获取用户输入的更可取的方式。请注意在两次调用
getline时,我们都使用了相同的字符串标识符 (
mystr)。程序在第二次调用中所做的只是将先前的内容替换为引入的新内容。
stringstream
标准头文件
<sstream>定义了一个名为
stringstream的类,它允许将基于字符串的对象视为流。这样,我们可以从字符串执行提取或插入操作,这对于将字符串转换为数值反之亦然特别有用。例如,如果我们想从字符串中提取一个整数,我们可以写
1 2 3
|
string mystr ("1204");
int myint;
stringstream(mystr) >> myint;
|
这声明了一个值为
string的对象,和一个
"1204"对象。然后我们使用
int的构造函数来从字符串对象构造此类型的对象。因为我们可以像使用流一样使用
stringstream对象,所以我们可以从中提取一个整数,就像我们在
stringstream上做的那样,通过应用提取器运算符 (
cin),后跟一个类型为
>>的变量。在这段代码之后,变量
int.
myint
将包含数值1776
1204.
|
// stringstreams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main ()
{
string mystr;
float price=0;
int quantity=0;
cout << "Enter price: ";
getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: ";
getline (cin,mystr);
stringstream(mystr) >> quantity;
cout << "Total price: " << price*quantity << endl;
return 0;
}
|
Enter price: 22.25
Enter quantity: 7
Total price: 155.75 |
。在这个例子中,我们间接地从标准输入获取数值。我们不是直接从标准输入中提取数值,而是将标准输入中的行 (
cin) 获取到一个字符串对象 (
mystr) 中,然后我们将这个字符串中的整数值提取到一个 int 类型的变量 (
quantity).
) 中。使用这种方法,而不是直接提取整数值,我们可以更好地控制用户输入数值时发生的事情,因为我们将从用户那里获取输入的过程(我们现在只是请求行)与对该输入的解释分开。因此,在所有用户输入密集的程序中,通常首选这种方法来从用户那里获取数值。