第 12章 输入输出流
12.1 标准输入输出流
12.2 文件输入输出流
C++语言程序设计教程与实验 第 12章 输入输出流
就像 C语言一样, C++语言中也没有专门的输入 /输出语句 。
C++的 I/O是以字节流的形式实现的, 每一个 C++编译系统都
带有一个面向对象的输入 /输出软件包, 这就是 I/O流类库 。 其
中, 流是 I/O流类的中心概念 。
所谓流, 是指数据从一个对象流向另一个对象, 是从源到
矢的数据流的抽象引用, 它是描述数据流的一种方式 。 C++
的输入输出系统是对流的操作, 也就是将数据流向流对象,
或从流对象流出数据 。 在 C++程序中, 数据可以从键盘流入
到程序中, 也可以从程序中流向屏幕或磁盘文件, 把数
12.1标准输入输出流
12.1.1 输入输出流的概念
C++语言程序设计教程与实验 第 12章 输入输出流
据的流动抽象为,流,。 流在使用前要被建立, 使用后要被 删除
,还要使用一些特定的操作从流中获取数据或向流中添加数据 。 从
流中获取数据的操作称为提取操作, 向流中添加数据的操作称为插
入操作 。
流是 C++流库用继承方法建立起来的一个输入 /输出类库, 它具
有两个平行的基类即 streambuf类和 ios类, 所有其它的流类都是从
他们直接或间接地派生出来的 。
在 C++语言系统中所有的流式输入输出操作都是借助 ios类及其
派生类对象实现的 。 与 cout和 cin相关的类名为输出流类 ostream和
输入流类 istream,此二类都是 ios类的派生
C++语言程序设计教程与实验 第 12章 输入输出流
类 。 cin是 istream类的一个对象; cout是 ostream类的一
个对象 。 此二对象的特殊之处在于它们是编译器直接认识
的系统级的对象 。 而类 ostream和 istream则是在 iostream.h
头文件中声明的 。 实际上 C++语言所支持的各种
流式输入输出的许多保留名都是某个具体类的对象名或对
象成员名 。
由 ios类可派生出许多派生类, 而每个类的对象也不只
是内定的 cin和 cout,甚至可由用户定义对象用以支持不同
要求的流式输入输出 。 符号, <<”和, >>”则是在类 ( 派生类
) 中定义的重载运算符函数 。
C++语言程序设计教程与实验 第 12章 输入输出流
C++语言为实现数据的输入输出定义了许多复杂的类
,这些类都以 ios为基类,其余都是它的直接或间接派生
类。这些类以及它们之间的关系如图 12.1所示。
每种类标识符代表的含义如下,
ios,根基类
ostream,输出流类
istream,输入流类
fstreambase,文件流基类
strstreambase,字符串流基类
ofstream,输出文件流类
12.1.2 C++所有输入输出类的继承关系
C++语言程序设计教程与实验 第 12章 输入输出流
ifstream,输入文件流类
ostrstream,输出字符串流类
istrstream,输入字符串流类
iostream,输入输出流类
fstream,输入输出文件流类
strstream,输入输出字符串流类
C++语言程序设计教程与实验 第 12章 输入输出流
ios
istream fstreambase strstreambase ostream
ifstream istrstream ofstream ostrstream
iostream
fstream strstream
C++语言程序设计教程与实验 第 12章 输入输出流
标准 I/O 对象
cin:标准输入, 默认设备为键盘, 是 istream类的对象
cout:标准输出, 默认设备为屏幕, 是 ostream类的对

cerr:标准错误输出, 没有缓冲, 发送给它的内容立即
被输出, 默认设备为屏幕 。 是 ostream类的对象 。
clog:带缓冲的标准出错信息输出,有缓冲, 当缓冲区
满时被输出, 默认设备为打印机, 是 ostream类的对象 。
上面的四个对象包含在 iostream.h标准头文件中。
1.标准流的设备名
C++语言程序设计教程与实验 第 12章 输入输出流
C++流类提供了许多控制输入输出的成员函数, 通过,或 ->
加以调用 。 例如,get(),getline()函数 。 虽然可以利用成员
函数实现输入, 输出, 但非常不方便, 为此 C++中通过重载 >>和
<<运算符来实现数据的输入输出, 同时为了便于对输入输出的
控制, 又提供了许多可与 >>和 <<配合使用的特殊函数, 称为操
作符或控制符 。 例如,endl和 setw就是操作符 。
cout是 ostream类的全局对象, 它在头文件 iostream.h中
的定义如下,
ostream cout(stdout); //这里, stdout作为该对象构
造时的参数对应每种基本数据类型, ostream类存在友元, 它们
都在 iostream.h中声明 。 例如,
2.原理
C++语言程序设计教程与实验 第 12章 输入输出流
ostream& operator<<(int n);
ostream& operator<<(float f);
ostream& operator<<(const char*psz);
如下列语句,
cout<< "How old are you?";
cout是类 ostream的对象, <<是插入运算符, 右面是
char*类型, 所以, 应该匹配上面第三个友元函数 。 它将整
个字符串输出, 并返回 ostream流对象的引用 。
同理, cin是 istream的全局对象, istream类也存在友
元 。 例如,
istream& operator>>( float &f);
istream& operator>>( int &n);
istream& operator>>( char*psz);
C++语言程序设计教程与实验 第 12章 输入输出流
经常使用的控制符已在第三章中介绍过, 下面介绍常用的
流对象成员函数 。
precision():设置显示小数精度, 用于 cout。
width():设置域宽, 用于 cout。
flags():设置基数和填充字符, 用于 cout。
get():读取一个字符或一系列字符直到输入流中出现结束
符或所读字符个数已达到要求读的字符个数, 用于 cin。
cin.get()从输入流中输入一系列字符时不包括回车符, 而
getline()却可以包括 。 单个字符时,cin.get()不跳过空白字
符 。 而 cin>>letter将跳过任何在文件中发现的任何空白字符 。
getline(char *line,int size,char='\n')读取一行字符,
用于 cin。 其中, 第一个参数是字符指针, 用于放置读取的文本
,
3.输入输出函数
C++语言程序设计教程与实验 第 12章 输入输出流
第二个参数是本次读取的最大字符个数, 第三个参数
是分隔字符, 作为读取一行结束的标志, 缺省为 '\n'

read():读取一个字符串, 用于 cin。
Put():输出一个字符, 用于 cout。
Write():输出一个字符串, 用于 cout。
【 例 12.1】 下面程序将用户的输入显示到屏幕上,输入
字母 y时输出 OK并结束 。
C++语言程序设计教程与实验 第 12章 输入输出流
#include <iostream.h>
#include <ctype.h>
void main()
{
char letter;
while (1)
{
letter=cin.get();
if (toupper(letter)=='Y')
{
cout<<"OK!";
break;
}
cout<<letter;
}
}
C++语言程序设计教程与实验 第 12章 输入输出流
#include <iostream.h>
void main()
{
char ch;
for (ch='a';ch<='z';ch++)
{
int i=ch;
cout.put(ch);
cout.width(6);
cout<<i<<endl;
}
}
例 12.2 下面程序将英文字母及对应的 ASCII值输出到屏幕上
C++语言程序设计教程与实验 第 12章 输入输出流
由于 C++允许重载插入运算符, 这使得用户可根据自己的
需要为插入运算符赋以新的含义, 使它按用户的意愿输出类
的内容 。 例如, 下面的程序重载了插入运算符使其能输出人
民币对象 。
【 例 12.3】 重载插入运算符
4.重载插入运算符
C++语言程序设计教程与实验 第 12章 输入输出流
【 例 12.3】 重载插入运算符
#include <iomanip.h>
class RMB
{
public,
RMB(double v=0.0)
{
yuan=unsigned(v);
jf=unsigned((v-yuan)*100.0+0.5);
}
operator double()//类类型转换函数
{
return yuan+jf/100.0;
}
C++语言程序设计教程与实验 第 12章 输入输出流
void display(ostream& out)
{
out<<yuan<<'.'<<setfill('0')
<<setw(2)<<jf<<setfill(' ');
}
protected,
unsigned int yuan;
unsigned int jf;
};
ostream& operator << (ostream& ot,RMB& d)
{
d.display(ot);
return ot;
}
C++语言程序设计教程与实验 第 12章 输入输出流
void main()
{
RMB rmb(2.3);
cout<<"Initially rmb="<<rmb<<"\n";//调用重载插
入运算符函数
rmb=2.0*rmb;
cout<<"then rmb="<<rmb<<"\n";
}
运行结果,
Initially rmb=2.30
Then rmb=4.60
C++语言程序设计教程与实验 第 12章 输入输出流
文件流是一个 I/O中非常重要的一个内容, 它的输入是指
从磁盘文件流向内存, 它的输出是指从内存流向磁盘 。 C++中
提供了三个文件流类,ofstream,ifstream,fstream,定义
在 fstream.h头文件中 。 其中 fstream是以 ofstream类和 if
stream类为基类的多重继承的子类 。 各文件流类的功能如下,
ofstream:输出流类, 用于向文件中写入内容 。
ifstream:输入流类, 用于从文件中读出内容 。
fstream:输入输出流类, 用于既要读又要写的文件的操
作 。
12.2 文件输入输出流
C++语言程序设计教程与实验 第 12章 输入输出流
每种文件流类都提供了构造函数用于文件的操作, 下面是
ofstream类在操作时主要用到的一个构造函数,
第一个参数指文件路径及文件名字符串,第二个参数说
明文件打开方式,第三个参数说明文件保护方式。打开方式
如表 12.1所示,文件保护方式如表 12.2所示。
oftream::ofstream(char * pFileName,int
mode=ios::out,
int prot=filebuf::openprot);
C++语言程序设计教程与实验 第 12章 输入输出流
标志
含义
ios::ate
如果文件存在, 输出内
容加在末尾
ios::in
具有输入能力
( ifstream默认 )
ios::out
具有输出能力
( ofstream默认 )
ios::trunc
如文件存在, 清除文件
内容 ( 默认 )
ios::nocrea
te
如文件不存在, 返回错

ios::norepl
ace
如文件存在, 返回错误
ios::binary
以二进制方式打开文件
标志
含义
filebuf:
:openpro
t
兼容共
享方式
filebuf:
:sh_none
独占,
不共享
filebuf:
:sh_read
允许读
共享
filebuf:
:sh_writ
e
允许写
共享
表 12.2 文件保护方式选择项
C++语言程序设计教程与实验 第 12章 输入输出流
#include <iostream.h>
#include <fstream.h>
#include <string.h>
void main()
{
ofstream myf(“d:\\myabc.txt”);//默认 ios::out和
ios::trunc方式
char txt[255];
while (1)
{
cin.getline(txt,255);
if (strlen(txt)==0)
例 12.4下面的程序可由用户输入任意一些字符串并按行保存到
磁盘文件中
C++语言程序设计教程与实验 第 12章 输入输出流
break;
myf<<txt<<endl;
}
}
注意,
(1) 文件名说明其路径时要使用双斜杠, 因为 C++编译器
理解单斜杠为转义字符 。
(2) 在文件打开时,匹配了构造函数
ofstream::ofstream(char*),只需要一个文件名,其它为
默认。打开方式默认为 ios::out | ios::trunc,即该文件
用于接受程序的输出。如果该文件已存在,则其内容必须先
清除,否则就新建。
(3)如果只在文件末尾添加内容, 则选择打开方式为
ios::ate即可 。
C++语言程序设计教程与实验 第 12章 输入输出流
(4) 如果要打开一个同时用于输入和输出的文件, 则用如下
方式,
fstream fc("myfile",ios::in | ios::out);
例 12.5编程将上面文件内容输出到屏幕上
#include <iostream.h>
#include <fstream.h>
#include <string.h>
void main()
C++语言程序设计教程与实验 第 12章 输入输出流
{
ifstream myf("d:\\myabc.txt",ios::nocreate);
if (myf.fail()) //如果要检查文件是否打开,则须判断成员函数
fail( ),
{
cout<<"file no exist!"<<endl;
return;
}
char txt[255];
myf>>txt;
while (!myf.eof())
{
cout<<txt<<endl;
myf>>txt;
}
}