2009-7-28 1
第 14章输入 /输出流类库
2009-7-28 2
输入输出,指程序与计算机的外部设备之间进行信息交换。
输出操作,将一个对象转换为一个字符序列,输出到某地方。
输入操作,从某地方接收一个字符序列,转换为对象要求的格式赋给对象。
目的,接收输出数据的地方。
源,输入数据来自的地方。
输入输出的本质,字符序列源 目的流动故将输入 /输出操作的类体系称为 流类,提供这个流类实现的系统称为 流类库 。
2009-7-28 3
建议使用概述两套方法:
与 C语言兼容的输入 /输出库函数
输入 /输出流类库流( Stream)
什么是流?是有向的数据流动的抽象描述,是数据流动的渠道和方向,是程序与输入 /输出设备的连接桥梁。如:
cin >> name; //从流对象(键盘)读数据放入变量中
cout <<?my name is? << name << endl;
//将数据写到流对象(屏幕)中
2009-7-28 4
两种类型的流:文本流、二进制流文本流,一串 ASCII字符,如源程序文件、文本文件。
可直接输出至显示器或打印机上。
二进制流,将数据以二进制的形式存放,传输时不要作变换。
程序输入设备输出设备文件
2009-7-28 5
使用流的优点:
减少使用不当引起的程序错误
减少成员函数文件文件 是 C++对具体设备的抽象。如:一个源程序、一个描述类的数据结构、一个可执行程序、一台显示器、
一台打印机等。
文件可具有不同的行为,即执行不同的操作。如:将数据写入磁盘文件或取出;将数据写入打印机文件等。
2009-7-28 6
缓冲缓冲区,系统在内存中开辟的专用来临时存放输入 /输出信息的区域。
输入 /输出流缓冲的:当缓冲区满时或当前送入的数据为新的一行字符时才处理。
非缓冲的:一旦数据送入流立即处理。
提高系统效率 一般使用缓冲流,特殊情况使用非缓冲流
2009-7-28 7
均包含在头文件 iostream.h中
C++的基本流类体系基本流类体系
ios streambuf
istream ostream
iostream
输入 /输出的基本流类体系基类类 ios中有一个指针成员指向类
streambuf的一个对象。其作用是管理流的缓冲区。
类 ios的公有派生类,提供完成输入操作的成员函数。
类 ios的公有派生类,提供完成输出操作的成员函数。
由 istream和
ostream公有派生,可完成输入 /输出操作。
2009-7-28 8
预定义的标准流与提取和插入运算符四个标准流对象,cin,cout,cerr,clog。
类 istream
公有派生类 istream_withassign
cin为其对象类 ostream
公有派生类 ostream_withassign
cout,cerr,clog为其对象
2009-7-28 9
流 cin
标准输入流。默认设备键盘,实现从键盘输入数据。
流 cout
标准输出流。默认设备显示器,实现从显示器上显示数据。
流 cerr
流 clog 标准错误信息输出流。默认显示器。
缓冲流非缓冲流标准流通过重载,>>”和,<<”执行输入 /输出称 提取运算符称 插入运算符使用,>>”实现其余使用,<<”实现输入 /输出时系统自动完成数据类型的转换
2009-7-28 10
字符序列 二进制数或 ASCII码转换输入流赋给变量输出数据 字符串转换输出流文件
2009-7-28 11
例 1,使用流 cerr和 clog实现数据的输出。
1401
本例中可用 cout代替 cerr和 clog。其作用相同。不同之处为:
流 cout允许输出重定向,而 cerr和 clog不允许。
一般提示输入数据的信息用流 clog,
提示错误信息用流 cerr,输出的结果数据用流 cout。
2009-7-28 12
注:
1,cin输入多个数据时,键盘输入不要用逗号隔开,只需用空格或换行将数值隔开。 如:
cin >> x >> y;
输入为,10 20
不能输入为,10,20
2,类型的匹配问题:不同类型的变量一起输入时,系统除检查是否有空白,还要检查输入数据与变量的匹配问题。如:
cin >> i >> x //i为整型,x为实型若输入 56.79 32.85
结果为,i=56,x=0.79
而不是 i=56,x=32.85
3,输入字符串时,字符串中不能有空格,一旦遇到空格,就当着是本数据结束。如:
cin >> str;
当输入为 We are students!
结果为 str=We,而不是 str=We are student!
2009-7-28 13
流的格式控制标准输入 /输出流的不足之处:
整型变量输入的数只能是十进制、八进制、十六进制;
只能用十进制数输出整数;
制表输出数据不能指定每个输出的数据占用的宽度。
流的格式化输入 /输出可解决,但只适用于文本流。
介绍常用的格式控制方法。
2009-7-28 14
控制输入 /输出格式的目的
进行不同进制之间的转换,8进制,16进制等
精度的控制:小数点的位数等
输入 /输出的宽度控制。如:是输出 100,还是 100
格式之间的状态转换控制输入 /输出格式的方法
使用 ios类中的有关格式控制的成员函数即由 cin 或 cout 流对象来调用其成员函数如,cout.width(4); cout.precision(5);
使用操作函数控制格式不要前缀流对象,直接调用操作函数。可以直接嵌入到输入 /输出语句中。
cout << setw(10) << hex << n << endl;
2009-7-28 15
格式控制函数名 功 能 适用于输入、输出流
dec 设置为十进制 I/O
hex 设置为十六进制 I/O
oct 设置八进制 I/O
ws 提取空白字符 I
endl 插入一个换行符 O
flush 刷新流 O
resetioflags(long) 取消指定的标志 I/O
setioflags(long) 设置指定的标志 I/O
setfill(int) 设置填充字符 O
setprecision(int) 设置实数的精度 O
setw(int) 设置宽度 O
ends 插入一个表示字符串结束的
NULL字符
C++中预定义的格式控制函数预定义的格式控制函数均包含在头文件
,iomanip.h”中
2009-7-28 16
例 2,使用格式控制函数实现指定域宽和数制。
1402setw设置仅对其后的一次插入有效。
使用缓冲区若欲将输出信息送到缓冲区后立即输出,必须强制刷新输出流。刷新输出流可用函数 flush实现。
例 3,输出的信息在显示器上不显示。
1403
2009-7-28 17
流的错误处理可用系统提供的错误检测功能检测。类 ios中的名为
io_state公有枚举类型:
enum io_state{
goodbit=0x00,//输入 /输出操作正常
eofbit=0x01,//已到达文件尾
faibit=0x02,//输入 /输出操作出错
badbit=0x04 //非法输入 /输出操作
};
发生输入 /输出错误时,系统设置状态位。用户可用类 ios
中提供的成员函数读取状态,并作相应处理。
2009-7-28 18
这些成员函数为:
int ios::rdstate( )const{return state; }
//读取输入 /输出状态字
int ios::bad( )const{return state &badbit; }
//状态字的 badbit位为 1时,返回值为非零值 (4),否则返回值为 0
void ios::clear(int_i=0 ){state=_i; }
//清除流中的错误
int ios::eof( )const{return state &eofbit; }
//用来判断是否到达文件尾,若到达则返回非零值,否则返回零
int ios::fail( )const{return state &(badbit | failbit; }
//流出现输入 /输出错误或非法操作时,返回非零值,否则返回零
int ios::good( )const{return state= =0; }
//流输入 /输出操作正常时返回值 0,否则返回 1
2009-7-28 19
例 4,输入不正确的数据时,导致程序出错。
如若要清除状态字中的某一个状态位,可使用如下形式:
cin.clear(cin.rdstate( )&~ios::badbit);
//将流中的非法输入 /输出操作位置为 0
cin.clear(cin.rdstate( ) | ~ios::badbit);
//将流中的非法输入 /输出操作位置为 1
不适当的输入 /
输出检测可能导致程序不能正常运行!1404
例 5,输入不正确的数据时,取完缓冲区中的字符。
1405
2009-7-28 20
标准设备的输入 /输出三大类数据的输入 /输出,字符类,字符串类,数值类 。
不同类型数据的输入由类 istream通过多次重载,>>”实现;
不同类型数据的输出由类 ostream通过多次重载,<<”实现。
不同类型数据的输入当程序中包含头文件,iostream.h”时,系统自动为该程序产生输入流 cin和输出流 cout。
例 6,使用 cin示例。 1406
2009-7-28 21
当输入,256 ff”时,程序执行正确;当输入,r ff”时输出

i=0
j=31376764
此时出错。
注,1.cin是缓冲流,仅当输入一行的结束符时,才开始提取数据处理。
2.输入数据时,缺省下将空格作为数据间的分隔符。
如,char c1,c2,str1[80];
cin>>c1>>c2>>str1;
则输入给变量 c1和 c2的字符不能是空格,给 str1的字符串中也不能有空格。
3.输入的数据类型必须与对应提取的数据类型一致。
2009-7-28 22
4.输入数据时,换行符有两个作用:
告诉系统已输入到缓冲区中的数据可以提取了;
从输入流中提取数据时,作为空格处理。
如,int i,j,k;
cin>>i>>j>>k;
当输入数据,1 3 6<Enter>
或分三行输入,1<Enter>
3<Enter>
6<Enter>
均为将 1,3,6分别赋给变量 i,j,k。
2009-7-28 23
输入操作的成员函数欲将空格也作为字符输入时,可利用类 istream中的成员函数。常用的输入字符或字符串的成员函数有:
int istream::get( );
//从输入流中提取一个字符,并将所提取的字符作为返回值
istream& istream::get( char &);
istream& istream::get(unsigned char & );
istream& istream::get(signed char & );
//以上三个函数均为从输入流中提取一个字符,并将该字符
//赋给输入参数的字符变量
istream& istream::get(char *,int,char=?\n?);
istream& istream::get(unsigned char *,int,char=?\n?);
istream& istream::get(signed char *,int,char=?\n?);
//以上三个函数均是从输入流中提取一个字符串,并将该字符
//串赋给第一个输入参数所指向的存储区;第二个参数为至多
//提取的字符个数;第三个参数为结束字符,缺省为换行符
2009-7-28 24
istream& istream::getline(char *,int,char=?\n?);
istream& istream::getline(unsigned char *,int,char=?\n?);
istream& istream::getline(signed char *,int,char=?\n?);
//以上三个函数均为从输入流中提取一个输入行,把输入行作为一
//个字符串送到第一个参数所指向的存储区。三个参数的作用同前例 7,读取字符和字符串。
1407执行时依次输入,abc<Enter>
computer part.<Enter>
operater systems<Enter>
则输出:
c1=a c2=b c3=c
str1=computer part.
str2=operater systems
2009-7-28 25
注,1.用 get函数提取字符或字符串时,要单独提取换行符。
2.用 getline函数提取字符串时,若实际提取的字符个数小于第二个参数指定的字符个数时,将输入流中的表示字符串结束的字符也提取出来,但不保存。
还有两个成员函数:
istream& istream::ignore(int=1,int=EOF);
//从输入流中提取由第一个参数所规定的字符个数,缺省为 1;第二
//个参数为要提取的结束字符,缺省为文件结束标志,EOF在头文件
//“iostream.h”中定义为 -1
int istream::gcout( )const{return x_gcout; }
//返回最近一次提取的字符个数例 8,使用函数 gcout和 ignore。 1408
若输入:
abcd Abort
computer depart.
则输入,c1=a
str1=computer depart.
num=17
2009-7-28 26
不同类型数据的输出
C++的三个标准输出流,cout,cerr,clog。
缺省设置:
输出整数
数制为十进制,域宽为 0,数字右对齐,以空格填充。
输出的实数的整数部分超过七位或有效数字在小数点右边第四位之后,转换为科学计数法输出。
输出字符或字符串
域宽为 0,字符右对齐,以空格填充。
2009-7-28 27
输出字符的成员函数类 ostream中如下部分成员函数可用来输出字符:
ostream& ostream::put(char);
ostream& ostream::put(unsigned char);
ostream& ostream::put(signed char);
//以上三个函数功能相同,参数为欲输出的字符
//如,int i=96;
// cout.put((char)i);
ostream& ostream::put(char);
//刷新一个输出流。如:
// cout.flush( );
通常只有 cout和
clog需要调用 flush
来强制刷新输出流的缓冲区
2009-7-28 28
例 9:
#include<iostream.h>
#include<iomanip.h>
void main( )
{ int n;
cout << " Enter a decimal number,";
cin >> n;
cout << n << " in hexadecimal is,"
<< hex << n << endl
<< dec << n << " in octal is,"
<< oct << n << endl
<< setbase(10) << n << " in decimal is," << n << endl;}
整数的不同进制转换结果,Enter a decimal number,20
20 in hexadecimal is,14
20 in octal is,24
20 in decimal is,20
2009-7-28 29
例 10:
#include<iostream.h>
#include<iomanip.h>
#include<math.h>
void main( )
{ double x=sqrt(2.0);
for(int index=0; index<=7; index++)
{ //使用 ios的成员函数
cout.precision(index);
cout << x << endl; }
cout << endl;
for(int index=0; index<=9; index++)
{ cout << setprecision(index)
<< x << endl; //使用操作函数 } }
实数的精度控制 结果,1.414214
1.4
1.41
1.414
1.4142
1.41421
1.414214
1.4142136
1.414214
1.4
1.41
1.414
1.4142
1.41421
1.414214
1.4142136
2009-7-28 30
例 11:
#include<iostream.h>
#include<iomanip.h>
void main( )
{ int x=12345;
//缺省格式 与右端对齐
cout << "Default is on right:" << endl
<< setw(10) << x << endl << endl;
//调整到与左端对齐
cout.setf(ios::left,ios::adjustfield);
cout << setw(10) << x << endl << endl;
//再次调整到与右端对齐
cout.unsetf(ios::left);
cout << setw(10) << x << endl; }
打印宽度的控制结果:
Default is on right:
12345
12345
12345
2009-7-28 31
例 12:
#include<iostream.h>
#include<iomanip.h>
void main( )
{ int x=12345;
//缺省格式 与右端对齐
cout << "Default is on right:" << endl
<< setw(10) << x << endl << endl;
//调整到与右端对齐
cout.setf(ios::right,ios::adjustfield);
cout.fill('* ');
cout << setw(10) << x << endl << endl;
//再次调整到与左端对齐
cout.setf(ios::left,ios::adjustfield);
cout << setw(10) << setfill(' % ') << x <<
endl; }
格式输出中空白的填充结果:
Default is on right:
12345
*****12345
12345%%%%%
2009-7-28 32
例 13:
#include<iostream.h>
void main( )
{ double x=0.001234567,y=1.946e9;
//缺省格式输出
cout << "Displayed in default format:" << endl
<< x << '\t ' << y << endl << endl;
//调整到科学计算输出格式
cout.setf(ios:scientific,ios::floatfield);
cout << "Displayed in scientific format:" << endl
<< x << ' \t ' << y << endl;
//再次调整到固定输出格式
cout.setf(ios:fixed,ios::floatfield);
cout << "Displayed in fixed format:" << endl
<< x << ' \t ' << y << endl; }
科学计算等格式输出结果:
Displayed in default format:
0.001235 1.946e+09
Displayed in scientific format:
1.234567e-03 1.946e+09
Displayed in fixed format:
0.001235 1946000000
2009-7-28 33
重载提取和插入运算符重载运算符,<<”和,>>”时,在用户自定义的类中,将重载这两个运算符的函数说明为该类的友元函数。
重载提取运算符的一般格式:
friend istream& operator>>(istream &,类名 &);
//函数返回值必须是对类 istream的引用,第一个参数也是对类 istream的
//引用,它将作为运算符的左操作数;第二个参数为用户自定义类的
//引用,并作为运算符的右操作数。
重载插入运算符的一般格式:
friend ostream& operator<<(ostream &,类名 &);
//函数返回值必须是对类 ostream的引用,第一个参数也是对类 ostream的
//引用,它将作为运算符的左操作数;第二个参数为用户自定义类的
//引用,并作为运算符的右操作数。
2009-7-28 34
例 14,重载提取和插入运算符,实现对象的输入和输出。
1409执行时若输入:
125 56
则输出:
¥ 200元 55分
¥ 125元 56分要实现数据的输入和输出,在重载运算符的函数体内,还是要通过 cin和 cout来完成数据的输入和输出。
2009-7-28 35
文件流
C++中文件的两种含义,具体的外部设备。如打印机等。磁盘文件。
C++文件概述文件:一组有序的数据集合。
存放在磁盘上;每个文件有个文件名,文件名是由字母开头的字母数字序列。
两种文件,二进制文件,包含二进制数据文本文件( ASCII文件),由字符序列组成
2009-7-28 36
使用文件的方法打开文件 从文件中读取数据或将数据写入到文件中只有按写入的方式依次读取数据,
读取的数据才是正确的使用结束关闭文件注,C++无法检查从文件中读取数据类型的正确性,
故设计者要保证从文件中取出数据与原先写入数据类型的一致性!
2009-7-28 37
C++的文件流类体系类,ios
类,istream 类,ostream
类,ifstream 类,iostream 类,ofstream
类,fstream
类,streambuf
类,filebuf
C++预定义的文件流类体系用于管理文件的缓冲区实现将数据写入到文件中的各操作支持从输入文件中提取数据的各操作实现数据的输入和输出提供从文件中提取数据或将数据写入文件的各操作
2009-7-28 38
文件的打开与关闭
C++中使用文件的方法:
( 1)说明一个文件流对象。只能是类 ifstream,ofstream或
fstream的对象。如:
ifstream infile;
ofstream outfile;
fstream iofile;
( 2)使用文件流类的成员函数或者构造函数,打开一个文件。打开文件的作用是在文件流对象与要使用的文件名间建立联系。如:
infile.open(“myfile1.txt”);
outfile.open(“myfile2.txt”);
2009-7-28 39
( 3)使用提取运算符、插入运算符或成员函数对文件进行读写操作。如:
infile>>ch;
( 4)使用完文件后,使用成员函数关闭文件。如:
infile.close( );
打开文件文件流类体系中的三个打开文件的成员函数:
void ifstream::open(const char *,int=ios::in,int=filebuf::openport);
//对应于输入文件流
void ofstream::open(const char *,int=ios::out,int=filebuf::openport);
//对应于输出文件流
void fstream::open(const char *,int,int=filebuf::openport);
//对应于输入 /输出文件流指定打开文件的方式,输入文件流的缺省值 ios::in为按输入文件方式打开文件,输出文件流的缺省值 ios::out为按输出文件方式打开文件要打开的文件名或文件的全路径名指定打开文件时的保护方式,
与具体的操作系统有关,一般情况下只使用缺省值
filebuf::openprot,而不给出实参
2009-7-28 40
头文件,ios.h”中定义了文件打开方式的公有枚举类型:
enum open_mode{
in=0x01,//按读方式打开文件
out=0x02,//按写方式打开文件
ate=0x04,//打开文件时,将指针移到文件的未尾
app=0x08,//按增补方式打开文件
trunc=0x10,//将文件的长度截为 0,并清除文件原有内容
nocreate=0x20,//打开已存在的文件
noreplace=0x04,//创建一个新文件,通常与写方式同时用
binary=0x08 //打开二进制文件
};
可以用二进制按位或运算符,|”
将几种打开方式组合起来使用注,?以 in方式打开的文件,只能从文件中读取数据;
以 out方式打开的文件,只能将数据写入文件中;
用上面两种方式单独打开的文件,若文件不存在,则产生一个空文件,若文件存在,则先删除该文件再产生一个空文件;
2009-7-28 41
ate方式不能单独打开文件,必须与 in,out或 noreplace同时使用。如:
out|ate //在文件打开时,将文件指针移到文件的结尾处,
//文件中原有内容不变,向文件中写的数据增加到文件中
app是以写方式打开文件,当文件存在时,等同于 out|ate,
当文件不存在时,等同于 out。
以 trunc方式打开文件,若单独使用,则与 out相同。
以 nocreate方式打开文件,若文件不存在,则打开文件的操作失败,总是与读或写方式同时使用,但不能与 noreplace同时使用。
noreplace通常用来创建一个新文件,总是与写方式同时使用。与 ate或 app同时使用可以打开一个已存在的文件。
以 binary方式打开的文件是二进制文件,其余均是文本文件,总时与读或写方式同时使用。
2009-7-28 42
ifstream的成员函数 open缺省打开方式为读文件方式;
ofstream的成员函数 open缺省打开方式为写文件方式;
fstream的成员函数 open没有缺省打开方式,使用时必须注明打开文件的方式。如:
fstream file;
file.open(“myfile.txt”,ios::in | ios::out);
//以输入 /输出方式打开文本文件 myfile.txt
三个文件流类中都重载了相应的构造函数:
ifstream::ifstream(const char *,int=ios::in,int=filebuf::openport);
ofstream::ofstream(const char *,int=ios::out,int=filebuf::openport);
fstream::fstream(const char *,int,int=filebuf::openport);
2009-7-28 43
在说明三种文件流的对象时,通过调用各自的构造函数也能打开文件。如:
ifstream f1(“file.dat”); //以读方式打开磁盘文件 file.dat
ofstream f2(“fileo.txt”); //以读方式打开磁盘文件 fileo.dat
fstream f3(“file2.dat”,ios::in);
//以读方式打开磁盘文件 file2.dat
语句 ifstream f1(“file.dat”);等同于:
ifstream f1;
f1.open(“file.dat”);
通常打开文件均要判断是否打开成功。若成功
,文件流对象值为非零值,否则值为 0。
2009-7-28 44
打开文件的格式:
ifstream f1(“file.dat”);
if(!f1){
cout<<“不能打开输入文件:” <<“file.dat”<<?\n?;
exit(1);
}

char filename[256];
cout<<“输入文件名:”;
cin>>filename;
ifstream f5;
f5.open(filename,ios::in | ios::nocreate);
if(!f5){
cout<<“不能打开输入文件:” <<filename<<?\n?;
exit(1);
}
打开输入文件时,若指定
ios::nocreate,则文件不存在时打开失败;否则文件不存在时,仍产生一个空的输入文件。
2009-7-28 45
关闭文件对文件的操作结束后应及时关闭文件,理由如下:
( 1)关闭文件后系统自动收回该文件所占的资源;
( 2)关闭文件后可使一个文件流类的对象与多个文件建立联系;
( 3)执行 C++时允许打开文件的数量有限。
与打开文件相对应的三个文件流类各有一个关闭文件成员函数:
void ifstream::close( );
void ifstream::close( );
void fstream::close( );
三个成员函数用法相同。如:
ifstream infile(“f1.dat”);

infile.close( ); //关闭文件 f1.dat
2009-7-28 46
文本文件的使用基本操作与标准输入 /输出流的使用方式相同,可通过提取运算符,>>”和插入运算符,<<”来读写文件。
例 15,使用构造函数打开文件,并把源程序文件拷贝到目的文件中。
分析,先打开源文件和目的文件,依次从源文件中读取一个字节,并把所读取的字节写入目的文件中,直到源文件中的所有字节读写完为止。
1410该程序可正确拷贝任意类型的文件,对二进制文件,只要逐个字节拷贝即可
2009-7-28 47
例 16,使用构造函数打开文件,使用成员函数来实现文件的拷贝。
1411该程序也可正确拷贝任意类型的文件例 17,使用成员函数打开文件,并实现文件的拷贝。
1412该程序只能实现文本文件的拷贝
2009-7-28 48
例 18,设文本文件 data.txt中有若干个实数,每一个实数之间用空格或换行符隔开。求出文件中的这些实数的平均值。
分析,各设一个计数器和累加器,每从文件中读取一个实数时,计数器加 1,并把该数加到累加器中,直到把文件中的数据读完为止。把累加器的值除以计数器的值,得到平均值。
1413若文件 data.txt的内容为:
24 56.9 33.7 45.6
88 99.8 20 50 执行后输出:
平均值 52.25 count=8
2009-7-28 49
二进制文件的使用文件的读写操作二进制文件的读操作通过成员函数 read实现;写操作通过成员函数 write实现。
流类 istream和 ostream中分别重载了这两个函数:
istream& istream::read(char *,int);
istream& istream::read(unsigned char *,int);
istream& istream::read(signed char *,int);
//三个函数功能类似。由第二个参数所指定的字节数读到由
//第一个字符型指针所指向的存储单元中
ostream& istream::read(char *,int);
ostream& istream::read(unsigned char *,int);
ostream& istream::read(signed char *,int);
//三个函数功能类似。第一个参数指出要写到文件中字节串
//的起始地址,第二个参数指出要写入的字节数。
通过文件流的成员函数来实现二进制文件的输入 /输出
2009-7-28 50
C++在类 ios中提供了一个测试文件是否结束的成员函数:
int ios::eof( ); //当到达文件结束时,返回非零值;否则返回 0
例 20,从例 19中产生的数据文件 data.dat中读取二进制数据,并在显示器上按每行 10个数的形式显示。
1415
例 19,产生一个二进制数据文件,将 1~ 500之间的所有偶数写入文件 data.dat中。
1414
2009-7-28 51
例 21,把 0~ 900的 sin函数值写到二进制文件 SIN.BIN中。
1416
使用二进制数据的成员函数,由于一次读写的字节数较大,故提高了文件操作的速度例 22,使用成员函数 read和 write来实现文件的拷贝。
1417
该程序可实现任意文件类型的拷贝,包括文本文件、数据文件或执行文件等
2009-7-28 52
随机访问文件的函数前面所有的读写操作如下所示:
文件内容
point
n
读前文件内容
point
读后
2009-7-28 53
C++允许从文件中的任何位置开始读或写数据,称为 文件的随机访问 。
如下文件流类中定义的几个成员函数支持文件随机访问:
istream& istream::seekg(streampos);
istream& istream::seekg(streamoff,ios::seek_dir);
//以上两个函数均表示将文件指针移动到由参数所指定的字节处
streampos istream::tellg( );
//返回输入文件流的当前文件指针值
ostream& ostream::seekp(streampos);
ostream& ostream::seekp(streamoff,ios::seek_dir);
//以上两个函数均表示根据第二个参数的值来确定移动文件
//指针的方向。值若为 ios::beg,则将第一个参数值作为文件指针
//的值;若为 ios::cur,则将文件指针的当前值加上第一个参数值
//的和作为文件指针的值;若为 ios::end,则将文件尾的字节编号
//值加上第一个参数会珠和作为文件指针的值。
stream& ostream::tellp( );
//返回输出文件流的当前文件指针值
g是 get的缩写,
表示要移动输入流文件的指针
p是 put的缩写,
表示要移动输出流文件的指针
2009-7-28 54
streampos和 streamoff等同于类型 long,seek_dir在类 ios中定义为一个公有的枚举类型:
enum seek_dir{
beg=0,//文件开始处作为参考点
cur=1,//文件当前位置作为参考点
end=2 //文件结束处作为参考点
};
如下例按输入方式打开了二进制文件流对象 f,移动文件指针:
f.seekg(-50,ios::cur); //当前文件指针值前移 50个字节
f.seekg(50,ios::cur); //当前文件指针值后移 50个字节
f.seekg(-50,ios::end);
//若文件尾的编号为 5000,则文件指针移到 4950处
2009-7-28 55
移动文件指针时,必须保证移动后的指针值大于等于 0且小于等于文件尾字节编号,否则出错。
例 23,产生一个 5~ 1000之间的奇数文件(二进制文件),
将文件中的第 20~ 29之间的数依次读出并输出。
1418
分两步实现随机文件的读写:
将文件指针移到要开始读写的位置;
用前面介绍的文件读写函数进行读或写操作。
2009-7-28 56
以例说明(设已成功地打开了输入流对象 infile和输出流对象 outfile:
infile.seekg(-100,ios::cur);
//文件指针从当前位置前移 100个字节
infile.seekg(100,ios::cur);
//文件指针从当前位置后移 100个字节
outfile.seek(-100,ios::end);
//文件指针从文件尾开始向前移 100个字节
infile.seek(500);
//文件指针移到第 500个字节处文件指针值按从大到小的顺序移动,称为 前移 ;返之称为 后移 。
2009-7-28 57
1,ios 流库的结构,istream 和 ostream
3,输入 /输出格式控制的方法:
使用 ios 的成员函数
使用操作函数
cin.getline(buffer,SIZE);
cout.width(10);
cout << setw(10) << x;
cout << setw(10) << setfill('* ') << x;
2,流对象 cin一般指键盘。流对象 cout一般指屏幕。
本章小结
2009-7-28 58
通过对输入 (?)和输出 (?)运算符的重载,定义特殊的输入 /输出结构
(1) 在程序中包含头文件 fstream.h
(2) 定义流对象,如,ifstream myin; ofstream myout;
(3) 使用 open函数打开文件
(4) 进行文件的读 /写操作
(5) 使用 close函数关闭文件
外部文件名和 逻辑名的区别:
ofstream myout(“myfile,,ios::out,0); //定义流对象和打开文件
(1) myfile 是外部文件名,即一个具体的要写入数据的文件。
(2) myout 是程序中使用的流对象名,是 外部文件的逻辑名。
问题,? 多次读同一文件,每次从头读起,如何完成?
如何指向文件的结尾?
如何知道文件已结束?