基本输入/输出

到目前为止,前面章节的示例程序与用户的交互非常少,甚至没有。使用标准输入输出库,我们将能够与用户交互,在屏幕上打印消息并从键盘获取用户的输入。

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变量包含值24zipcode变量包含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流来完成的。运算符后面必须跟变量,该变量将存储要从流中提取的数据。例如

1
2
int age;
cin >> age;

第一条语句声明一个类型为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 从用户请求多个数据输入

1
cin >> a >> b;

等价于

1
2
cin >> a;
cin >> b;

在这两种情况下,用户必须提供两个数据,一个用于变量a,另一个用于变量和 bb,它们可以被任何有效的空白分隔符分隔:空格、制表符或换行符。

cin 和字符串

我们可以使用cin来获取带有提取运算符 (>>) 的字符串,就像我们使用基本数据类型变量一样

1
cin >> mystring;

但是,正如所说,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将包含数值17761204.

// 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).

) 中。使用这种方法,而不是直接提取整数值,我们可以更好地控制用户输入数值时发生的事情,因为我们将从用户那里获取输入的过程(我们现在只是请求行)与对该输入的解释分开。因此,在所有用户输入密集的程序中,通常首选这种方法来从用户那里获取数值。
Index
目录