*********************************************************
原文:http://www.cplusplus.com/doc/tutorial/
*********************************************************
基本输入输出
|
直到现在,在前面章节里的例程中只提供了一点与用户的交互。使用标准输入和输出库,我们将能够通过在屏幕上打印信息和得到用户从键盘的输入来与用户交互。
C++
使用一个叫做“流
(streams)
”的简便抽象来完成在像屏幕或键盘的连续媒体上的输入和输出操作。一个流是一个程序可以向其插入
/
提取字符的对象。我们不用关心与流关联的物理媒体的很多细节——我们只需要知道它可以接受或提供字符序列。
标准
C++
库包含在
iostream
头文件中,标准输入和输出流对象被声明在这个头文件中。
标准输出
(cout)
在缺省情况下,程序的标准输出是屏幕,被定义用来使用它的
C++
流对象是
cout
。
cout
被与“插入操作符”一起使用。“插入符”写作“ << ”(两个小于号)。
cout <<
"Output sentence"
;
// prints Output sentence on screen
cout << 120;
// prints number 120 on screen
cout << x;
// prints the content of x on screen
|
<<
操作符把它后面的数据插入到它前面的流中。在上面的例子中,它把字符串常量“
Output sentence
”,数字常量
120
和变量
x
插入到标准输出流
cout
中。注意,第一条代码里的那个句子被用双引号
( “ )
括了起来,因为它是一个由字符组成的字符串常量。无论何时只要我们想使用由字符组成的字符串常量,我们必须把它们用双引号
( “ )
括起来以免和变量名产生混淆。例如,这两条语句有着截然不同的结果:
cout <<
"Hello"
;
// prints Hello
cout << Hello;
// prints the content of Hello variable
|
插入操作符
( << )
可以在一条语句中多次使用,例如:
cout <<
"Hello, "
<<
"I am "
<<
"a C++ statement"
;
|
最后这条语句将会在屏幕上打印信息“
Hello, I am a C++ statement
”。当我们想要打印一组变量和常量或多于一个变量时,我们重复使用插入操作符
( << )
:
cout <<
"Hello, I am "
<< age <<
" years old and my zipcode is "
<< zipcode;
|
如果我们假设变量
age
的值是
24
、变量
zipcode
的值为
90064
,上面语句的输出结果将会是:
Hello, I am 24 years old and my zipcode is 90064
|
特别注意:除非我们显示的说明,否则
cout
不回在它的输出结束后加一个换行,因此下面的语句:
cout <<
"This is a sentence."
;
cout <<
"This is another sentence."
;
|
将会在屏幕上连续输出,而不会在他们之间有换行:
This is a sentence.This is another sentence.
即使我们已经把他们通过两个不同的插入操作符写到
cout
中的。为了在输出的中加入换行我们必须向
cout
中插入“新行字符
(new-line character)
”。在
C++
中一个新行字符通过“
/n(
反斜杠,
n)
”来指定:
cout <<
"First sentence./n "
;
cout <<
"Second sentence./nThird sentence."
;
|
这会产生如下输出:
First sentence.
Second sentence.
Third sentence.
此外,为了加入新行,你也可以使用endl操纵符。例如:
cout <<
"First sentence."
<< endl;
cout <<
"Second sentence."
<< endl;
|
会打印出:
First sentence.
Second sentence.
Second sentence.
endl
操纵符想插入‘
/n
’那样产生一个新行符,但当被用于有缓冲区的流时,它还有一个附加的行为:清空缓冲区。总之,在大多数情况下
cout
是无缓冲区的流,因此你可一个使用转义符
/n
和操纵符
endl
来显式的指明一个新行而不用管它们行为上的区别。
标准输入
(cin).
标准输入设备通常是键盘。在
C++
中处理标准输入是由使用
cin
流上的重载
(overloaded)
乐得提取操纵符
( >> )
来完成的。在这个操纵符的后面必须跟一个将要存储从流中提取出来的数据的变量。例如:
int age;
cin >> age;
|
第一条语句定义了一个叫做
age
的
int
类型的变量,第二条等待从
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
从用户处要求输入多个数据:
cin >> a >> b;
|
等价于:
cin >> a;
cin >> b;
|
在两种情况里,用户都必须给出两个数据,一个给变量
a
另一个给变量
b
,它们可以由任何有效的空白分隔符分开:一个空格,一个制表符或一个新行。
cin
和字符串
我们可以使用提取操纵符
( >> )
像得到基本数据类型变量那样得到字符串:
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 Souli?Hello Juan Souli?
What is your favorite team? LA Lakers
I like LA Lakers too!
|
注意我们是如何在两次调用
getline
时使用同一个字符串标识符
(mystr)
的。程序在第二次调用的时候,只是简单的用新的数据覆盖早先的内容。
stringstream(
字符串流
)
标准头文件
<sstream>
定义了一个叫做
stringstream
的类,它允许一个基于字符串的对象被像流一样对待。这样我们可以在字符串上进行提取或插入操作,特别是对把一个字符串转化为一个数学值,反之亦然。例如,如果我们想从一个字符串中提取一个整数,我们可以这样写:
string mystr (
"1204"
);
int myint;
stringstream(mystr) >> myint;
|
这里声明了一个有值
”1204”
的字符串对象,一个
int
型对象。然后我们利用
stringstream
的构造函数从那个字符串对象构造了一个这个类型
(stringstream)
的对象。因为我们可以像使用流一样使用
stringstream
对象,我们可以像从
cin
那里那样通过在提取操纵符
( >> )
后跟一个
int
类型的变量,来从它里面提取一个整数。
在这个代码片断后,变量
myint
将存有数值
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
型变量
(myint)
。
使用这个方法,而不是直接提取整数值,我们对从用户那里输入的数值量有更多的控制,因为我们通过解释输入来分隔了从用户处获得输入
(
我们现在只是要求一些行
)
的过程。因此,我建议你在所有的要求用户输入数字值的程序里,用这个方法来代替直接提取。
(第一章完)