第 11章 C++输入 /输出流
11.1 输入 /输出流的概念
11.2 输 出 流
11.3 输 入 流
11.1 输入 /输出流的概念在 C++程序中,数据可以从程序流向屏幕或磁盘文件,也可以从键盘或磁盘文件流入到程序中 。
在 C++语言中,数据的输入和输出操作包括以下几种情况:
( 1) 对标准输入设备 —— 键盘或标准输出设备 —— 显示器进行输入 /输出操作,简称为标准 I/O流 。
( 2),对外存 ( 如磁盘 ) 上的文件进行输入 /输出操作,简称为文件 I/O。
( 3) 对内存中指定的字符串存储空间进行输入 /输出操作,简称为串 I/O。
简单地讲,I/O流是一系列写到屏幕显示器上或从键盘上读出的各种字符 。 当在 C++
中执行标准的输入 /输出操作时,一般使用
I/O流 cin作为输入,使用 cout作为输出 。 事实上,C++将 I/O流定义为类 。 输入和输出操作分别由输入流 istream 和输出流
ostream两个类提供 。
而 iostream是这两个类的派生类,允许进行双向的 I/O操作 。 ostream的输出操作可认为是一个插入过程,由左移符 ( 或称作插入操作符 ),<<”实现,可以认为数据是被插入到输出流中 。 而 istream的输入操作则可认为是一个提取过程,由右移符
( 或称作提取操作符 ),>>”的操作符实现 。
任何一个使用 iostream库的程序都必须包含头文件 iostream.h。
在 C++语言中,有四个已预先定义好的流对象,以便用户直接使用,分别为:
( 1) cin:一个 istream类的对象,用于处理标准输入 。
( 2) cout:一个 ostream类的对象,用于处理标准输出 。
( 3) cerr:一个 ostream类的对象,用于处理标准出错信息,并提供不带缓冲区的输出;
( 4) clog:一个 ostream类的对象,也用于处理标准出错信息,但提供带有缓冲区的输出 。
11.2 输 出 流
11.2.1 基本输出操作
11.2.1.1 理解 cout
cout是 console output的缩写,意为,控制台输出,,表示把程序结果输出到屏幕
( 标准输出设备 ) 。
【 例 11.1】 cout应用举例 1。
#include <iostream.h>
void main(void)
{
cout<<”C++ is very easy!”<<endl;
}
运行程序,会在显示器上输出显示如下信息:
C++ is very easy!
插入操作符 <<可以串联起来使用,将多个数据项一起输出 。
【 例 11.2】 cout应用举例 2。
#include <iostream.h>
void main(void)
{
char name[]="Zhang San";
int age=25;
cout<<"Output the name and age,
"<<name<<" "<<age<<endl;
}
运行程序,输出结果为:
Output the name and age,Zhang San 25
【 例 11.4】 以十六进制形式输出显示结果 。
#include <iostream.h>
void main(void)
{
float x=888.;
float* p=&x;
cout<<"x:\t"<<x<<"\t&x:\t"<<&x<<endl;
cout<<"*p:\t"<<*p<<"\tp:\t"<<p<<endl;
cout<<"&p:\t"<<&p<<endl;
}
运行程序,输出结果为:
x,888 &x:
0x0012FF7C
*p,888 p:
0x0012FF7C
&p,0x0012FF78
11.2.1.2 常见错误
11.2.1.3 输出成员函数
1,put()函数成员函数 put( ) 把单个字符写入输出流中 。
【 例 11.5】 用输出成员函数在屏幕上输出一串字符,Hello!”。
#include <iostream.h>
void main(void)
{
cout.put('H');
cout.put('e');
cout.put('l');
cout.put('l');
cout.put('o');
cout.put('!');
cout.put('\n');
}
实际上,下面两条语句是等价的:
cout<<'a';
cout.put('a');
两者都在屏幕上输出一个字符 a。
2,write()函数成员函数 write( ) 输出一串字符 。 该成员函数一般形式是:
write( char* pch,int nCount)
其中,pch 是 指 向 字 符 数 组 的 指 针,
nCount指明从第一个参数中复制输出字符的个数 。
【 例 11.6】 write( ) 函数应用举例 。
#include <iostream.h>
void main(void)
{
char str[]="You will be the C++ master !";
cout.write(str,sizeof(str)-1);
cout<<endl;
cout.write(&str[4],4) <<endl;
}
运行程序,输出结果为:
You will be the C++ master !
will
11.2.1.4 重载插入操作符 <<
【 例 11.7】 使用成员函数 show_date显示
CDate类的时间信息 。
#include <iostream.h>
#include <string.h>
class Cdate
{
public:
CDate(char *Year,char *Month,char
*Date,char* Time);
void show_date(void);
private:
char Year[32];
char Month[32];
char Date[32];
char Time[32];
};
CDate::CDate(char *Year,char *Month,
char *Date,char *Time)
{
strcpy(CDate::Year,Year);
strcpy(CDate::Month,Month);
strcpy(CDate::Date,Date);
strcpy(CDate::Time,Time);
}
void CDate::show_date(void)
{
cout<<"Year:\t"<<Year<<endl;
cout<<"Month:\t"<<Month<<endl;
cout<<"Date:\t"<<Date<<endl;
cout<<"Time:\t"<<Time<<endl;
}
void main(void)
{
CDate current_date("2004年 ","2月 ","14日
","19时 25分 ");
current_date.show_date();
}
11.2.2 输出格式控制
11.2.2.1 操作器
1,控制浮点数显示精度 setprecision
可用 setprecision操作器来控制输出流显示的数据位数 。 默认状态下浮点数的输出精度是 6位有效数字 。
【 例 11.9】 setprecision应用举例 。
#include <iostream.h>
#include <iomanip.h>
void main(void)
{
cout<<"float:"<<endl;
for(int
i=1;i<8;i++)cout<<setprecision(i)<<200./7.<
<endl;
cout<<setiosflags(ios::fixed)<<"fixed:"<<e
ndl;
for(i=1;i<8;i++)cout<<setprecision(i)<<200.
/7.<<endl;
}
输出结果为:
float:
3e+001
29
28.6
28.57
28.571
28.5714
28.57143
fixed:
28.6
28.57
28.571
28.5714
28.57143
28.571429
28.5714286
2,控制输出进制 dec,oct,hex、
setbase
dec,oct,hex分别用于控制十进制,八进制和十六进制输出格式 。 默认状态下的输出流格式是十进制 。
【 例 11.10】 用不同的进制输出 200:
#include <iostream.h>
#include <iomanip.h>
void main(void)
{
int num=200;
cout<<"Default:\t"<<num<<endl<<"Deci
mal:\t"<<num<<endl;
cout<<"Octal:\t\t"<<oct<<num<<endl;
cout<<"Hexadecimal:\t"<<hex<<num<<en
dl;
cout<<setbase(16)<<
"Hexadecimal:\t"<<num<<endl;
}
输出结果为:
Default,200
Decimal,200
Octal,310
Hexadecimal,c8
Hexadecimal,c8
3,控制值的输出宽度 setw
可以使用 setw( int nw)操作器来确定输出域的宽度。如果一个值所需的字符数比
setw( int nw)给定的字符数 nw多,则该值将使用它所需的所有字符。如果一个值所需的字符数少,则数字前填充空格。
【 例 11.11】 setw应用举例 。
#include <iostream.h>
#include <iomanip.h>
void main(void)
{
for(int i=4;i<=8;i++)
cout<<setw(i)<<12345<<endl;
}
输出结果:
12345
12345
12345
12345
12345
4,控制填充字符 setfill
setfill( int nFill) 用来在空白处填充字符 。
5,其他操作器 ends,flush,ws
ends:插入空终结符 ( ‘\0’)
flush:刷新流 。
ws:仅用于输入,跳过空格 。
11.2.2.2 流的格式化标志
1,使用 setiosflags或 resetiosflags操作器设置格式操作器 setiosflags( long lFlags)用于设置由 lFlags标示的格式化标志。表 12.1给出了格式化标志及其作用。
表 12 - 1 i o s 格式化标志标志位 描述
i o s:,sk i p w s 输入时跳过空字符,默认为关闭。
i o s:,l e f t 左对齐输出。默认为打开。
i o s:,ri g h t 右对齐输出。默认为关闭。
i o s:,i n t e rn a l 数据的符号左对齐,数据右对齐,在符号和值之间填充内容。默认为关闭。
i o s:,d e c 以十进制格式显示整数值,默认为打开。
i o s:,o c t 以八进制格式显示整数值,默认为关闭。
i o s:,h e x 以十六进制格式显示整数值,默认为关闭。
i o s:,sh o w b a se 输出有 基数标志显示的数值,默认为关闭。
i o s:,sh o w p o i n t 浮点数始终显示小数点,默认为关闭。
i o s:,u p p e rc a se 十六进制显示 A ~ F,科学计数法表示的值显示 E,默认为关闭。
i o s:,sh o w p o s 正数前显示‘ + ’,默认为关闭。
i o s:,sc i e n t i f i c 以科学计数法显示浮点数,默认为关闭。
i o s:,f i x e d 用定点数形式显示浮点数,默认为打开。
i o s:,u n i t b u f 在完成插入操作后立即刷新流的缓冲区,默认为关闭。
i o s:,sd i o 在完成插入操作后刷新系统 的 std o u t 和 std e rr 流,默认为关闭。
【 例 11.12】 格式化标志的应用举例 。
#include <iostream.h>
#include <iomanip.h>
void main(void)
{
double pie=3.1415926,x=3.5;
int n=255,m=300;
cout<<n<<endl;
//默认状态下为十进制
cout<<setiosflags(ios::hex)<<n<<endl;
//十六进制
cout<<setiosflags(ios::hex|ios::uppercase)
//十六进制,字符大写
<<n<<endl;
cout<<setiosflags(ios::hex|ios::uppercase
|ios::showbase)<<n<<endl;
//十六进制,字符大写,带基指示符
cout<<setw(6)<<setiosflags(ios::right
//右对齐,十六进制,
|ios::uppercase|ios::showbase)
//字符大写,带基指示符
<<n<<endl;
cout<<m<<endl; //除左对齐外,其他与上条语句输出相同
//说明设置的标志位仍然起作用
cout<<resetiosflags(ios::hex)
//恢复为十进制
<<n<<endl;
cout<<pie<<endl; //默认输出浮点数
cout<<setiosflags(ios::showpos)
//输出带,+”
<<x<<endl;
cout<<setiosflags(ios::scientific)
//带,+”,科学计数法
<<x<<endl;
cout<<resetiosflags(ios::uppercase)
//恢复为小写 e,仍为科学计数法
<<pie<<endl;
cout<<setiosflags(ios::fixed)
//带,+”,定点数
<<x<<endl;
cout<<setiosflags(ios::showpoint)
//带,+”,定点数,带小数点
<<x<<endl;
cout<<resetiosflags(ios::showpoint|ios::sho
wpos) //去除定点和,+”
<<x<<endl;
}
输出结果为:
255
ff
FF
0XFF
0XFF
0X12C
255
3.14159
+3.5
+3.500000E+000
+3.141593e+000
+3.5
+3.50000
3.5
2,使用成员函数设置格式
setf( long lFlags) 函数用来设置格式化标志,
unsetf( long lFlags) 函数是恢复标志位 。
11.2.2.3 格式化成员函数
1,填充和获取字符的成员函数 fill
fill是重载函数,分别为 fill( char nFill) 和
fill( )
fill( char nFill)
用于填充字符 。
例如:
cout.fill(‘a’);

cout.fill(100);
fill( ) 用于获取当前的填充字符 。 例如:
cout<<setfill(65);
cout<<cout.fill()<<endl;
将在屏幕上输出字符,A”。
2,设置或获取浮点精度成员函数
precision
precision是重载函数 。 成员函数 precision
( int nP) 用于设置浮点值的精度,
成员函数 precision( ) 用于获取当前精度 。
例如:
cout.precision(3);
……
cout<<cout.precision()<<endl;
将在屏幕上输出精度,3
3,设置或获取域宽成员函数 width
width是重载函数 。 成员函数 width( int nw)
用于设置域宽,
成员函数 width( ) 用于获取当前域宽 。 例如:
cout.width(8);
……
cout<<cout.width()<<endl;
将在屏幕上输出结果,ddddddd8。
11.3 输 入 流
11.3.1 基本输入操作
11.3.1.1 理解 cin
cin是 console input的缩写,意为,控制台输入,,表示从键盘 ( 标准输入设备 )
输入数据 。
【 例 11.13】 cin应用举例 。
#include <iostream.h>
void main(void)
{
int year,month,day;
char ch;
cout<<"Please input year,month,day,"
cin>>year>>month>>day;
cout<<"This is the date:\t"<<year<<"-
"<<month<<"-"<<day<<endl;
cout<<"Please type in characters,";
for(int i=0;i<10;i++)
{
cin>>ch;
cout<<ch;
}
}
【 例 11.14】 处理输入的字符串 。
#include <iostream.h>
#include <string.h>
void main(void)
{
char name[15];
cout<<"Type in your name please,";
cin>>name;
cout<<"The name and it\'s length are:
"<<name<<" "<<strlen(name)<<endl;
}
11.3.1.2 输入成员函数
1,从流中获取一个字符(串)的成员函数 get
get是重载函数 。 成员函数 get( char &ch)
从输入流获取一个字符并把该字符存入 ch
中 。 成员函数 get( ) 从输入流中读入一个字符并将该字符的 ASCII码值作为函数的返回值 。
【 例 11.15】 成员函数 get应用举例。
#include <iostream.h>
#include <ctype.h>
void main(void)
{
char ch;
char chs[128];
cout<<"Please enter to continue:"<<endl;
cin.get();
cout<<"Please type in characters:"<<endl;
cin.get(chs,6,'k'); //此处 delim
设为 ‘k’,如输入 1234567,则 chs为 12345,
//如输入 12k4567,则 chs为 12
cout<<"You\'ve get,"<<chs<<endl;
cout<<"Please type in Y or N,";
do
{
cin.get(ch);
ch=toupper(ch);
}while(ch!='Y'&&ch!='N');
cout<<endl<<"you typed,"<<ch<<endl;
}
2,从流中读取输入行的成员函数
getline
成员函数 getline( char* pch,int nCount,
char delim = '\n') 从输入流中读入整行文本存入 pch。 如果遇到某个字符 delim或读到第 nCount个字符时返回 。 该函数最多读入 nCount-1个字符,换行符不被作为结束输入的特殊字符 。
【 例 11.16】 成员函数 getline应用举例 。
#include <iostream.h>
void main(void)
{
char line[10];
cout<<"Please type in line of text:"<<endl;
cin.getline(line,sizeof(line),'y');
cout<<"First line,"<<line<<endl;
cin.getline(line,sizeof(line),'y');
cout<<"Last line,"<<line<<endl;
}
3,从流中读取字符串的成员函数 read
成员函数 read( char* pch,int nCount) 从输入流中读取 nCount个字符,当输入流中的字符数小于 nCount时,结束读取 。 经常使用 read函数读取二进制数据 。
4,确定提取字符数成员函数 gcount
当程序从键盘提取字符时,可能需要确切知道提取的字符数 。 为此可使用成员函数
gcount( ) 。
5,忽略输入流中字符成员函数 ignore
当程序执行输入操作时,有时需要忽略输入流中的一些字符或某个字符之前的字符 。
成员函数 ignore( int nCount = 1,int delim
= EOF) 略去 nCount个字符,默认状态下
nCount默认为 1。
【 例 11.17】 成员函数 ignore应用举例 。
#include <iostream.h>
void main(void
{
char line[10];
cout<<"Please type in line of text,";
cin.ignore(4,'a');
cin.getline(line,sizeof(line));
cout<<"after ignore,"<<line<<endl;
}
下面是输入两串字符忽略后的输出结果:
Please type in line of text,
1234567890123456
after ignore,567890123
Please type in line of text,
12a4567890123456
after ignore,456789012
6,返退提取字符的成员函数 putback
成员函数 putback( char ch) 将从流中提取的字符在返退到流中 。 如果与返退的字符 ch
不是先前从流中提取的字符,结果不定 。
【 例 11.18】 成员函数 putback应用举例 。
#include <iostream.h>
void main()
{
char a,b,c,d;
cin>>a>>b>>c>>d;
cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;
cin.putback(b);
cin>>a>>b>>c>>d;
cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;
}
先从输入流中分别提取字符 a,b,c,d,
然后将 b返退到流当前的位置,如输入流是
123456789,则将 2放在 5之前。当前流成为
256789,两次读取的 a,b,c,d分别为,1、
2,3,4,2,5,6,7。
11.3.1.3 重载提取操作符 >>
【 例 11.19】 重载提取操作符 >>举例 。
#include <iostream.h>
#include <string.h>
class CDate
{
public:
CDate(int Year,int Month,int Day);
friend ostream& operator <<(ostream
&stream,CDate Date);
friend istream& operator >>(istream
&stream,CDate *Date);
private:
int Year;
int Month;
int Day;
};
CDate::CDate(int Year,int Month,int Day)
{
CDate::Year=Year;
CDate::Month=Month;
CDate::Day=Day;
}
ostream &operator<<(ostream &stream,
CDate Date)
{
stream<<Date.Year<<'/'<<Date.Month<<'/
'<<Date.Day<<endl;
return(stream);
}
istream &operator>>(istream &stream,
CDate *Date)
{
stream>>Date->Year;
stream>>Date->Month;
stream>>Date->Day;
return(stream);
}
void main(void)
{
CDate Marry_birthday (2004,1,22);
CDate birthday(2004,6,1);
cout<<" Marry_birthday is,"<<
Marry_birthday;
cout<<"Type in your birthday yyyy mm dd,
";
cin>>&birthday;
cout<<"Your birthday is,
"<<birthday<<endl;
}
11.3.2 输入格式控制
【 例 11.20】 输入格式控制距离 。
#include <iostream.h>
#include <iomanip.h>
void main(void)
{
int i,j,k;
cin.setf(ios::hex);
cin.fill('*');
cin>>setw(8)>>i>>oct>>j>>dec>>k;
cout<<i<<endl;
cout<<j<<endl;
cout<<k<<endl;
cout<<cin.width()<<endl;
cout<<cin.fill()<<endl;
}