04015221 - 步兆军 - 作业第 9 章(2)文件输入输出流

更新时间:2023-11-08 16:33:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

文件输入输出流 【学习要点】

1.掌握文件流类体系的组成和应用。

2.掌握文件的使用方法━━定义文件流、打开文件、读/写操作、关闭文件 3.掌握文本文件的使用━━>> 、<< 、get()、getline()、put() 4.掌握二进制文件的使用━━read()、write()

5.掌握文件的随机访问━━seekg()、tellg()、seekp()、tellp()

6.掌握文件与对象━━在构造函数中通过磁盘数据文件来初始化新建立的对象

━━在析构函数中将对象中的数据保存在磁盘数据文件

------------------------------------------------------------------------------------------------------------------------------------------------ 【例题分析】

1.下面程序的运行结束后,显示器上输出结果是______,数据文件data.dat中保存的结果是______。

#include void main( )

{ ofstream outf (\for ( int i=10;i<20;i++)

if (i%3==0) cout<

【答案】显示器上输出结果是:12 15 18

数据文件data.dat中保存的结果是:10 11 13 14 16 17 19

【解析】程序中循环控制变量i共循环10次,取值范围为10~19,其中能被3整除的通过标准输出流cout输出到显示器,其余的才通过自定义文件流outf输出到数据文件data.dat中。 2.若单词间只有一个空格,下面程序运行后显示器上的输出结果是______。 #include #include void main()

{ char c, *str=\

fstream inout ( \ ios::in|ios::out|ios::binary ) ; if ( !inout ) { cout<<\文件打开出错!\\n\inout<

inout.seekg ( 5, ios::beg );

while ( ! inout.eof() ) { inout.get(c); if (c==' ') cout<

①程序中按读/写方式打开一个二进制文件mydata.dat。

②对mydata.dat文件先写入一个字符串,由于字符的内部存储格式与ASCII码一样,所以此处可以用插入运算符“<<”替代write()来写。

③通过inout.seekg(5,ios::beg);语句把文件指针定位于第5号字符位置(即定位于r字符。注意:文件指针位置为0时,表示指向文件的起始位置)。

④然后依次读取字符,当读取字符为空格,则通过tellg()函数得到当前字符的位置。值得注意的是,起始字符位置从0开始算起,则are后面的两个空格位置应该是7和9,但程序结果并非是7和9而是8和10,原因是读取字符空格后,文件指针已经移到后面的一个字符上,所以程序输出的是空格后的字符位置。

***************************************************************************************************************************

1

3.编写面向过程的程序实现以下工作:将存放在两个文本文件(data1.txt、data2.txt)中已按递增顺序排列好的两个整数序列(两个文件中的整数个数不祥,但已按递增顺序排列好,整数之间以若干空格、或者回车换行间隔),进行合并统一递增排序后写入另一个文本文件mydata.txt中(按每行4个整数的格式),而原始数据文件data1.txt和data2.txt中的内容保持不变。 【面向过程程序的算法提示】

●文件读入:定义一个函数input(),完成将指定文件中的数据全部读入一个数组的工作,并返回数组中有效数据的个数。

int input ( char *filename , int *p , int max=100 ) ;

●有序合并:定义一个函数combine(),完成数组a、b有序合并到数组c的工作。

有序合并数组a和数组b的算法是:使用三个下标指针pa、pb和pc,初始值都为0,分别代表指向a、b、c三个数组的0号元素。从0号元素开始依次比较a、b两个数组中的元素,将较小者放入数组c中,然后pc增1,而pa、pb中的一个增1,另一个不变;若比较中出现两个元素相等,则先选择数组a的元素放入数组c中,然后pa增1,pc也增1。循环以上过程,直到a、b两个数组之一的元素比较完毕,然后将另一个未比较完毕的数组剩余元素拷贝到数组c的尾部。

void combine ( int *a, int m, int *b, int n , int *c ) ;

●写入文件:定义一个函数output(),完成将一个数组中的整数写入指定文件的工作,按每行4个整数的格式写入。

void output ( char *filename , int *p , int k ) ;

●显示输出:定义一个函数show(),完成将一个数组中的整数显示输出的工作,按每行4个整数的格式输出。

void show ( int *p , int mnk ) ; ●编写 main( ) 函数:

①定义两个命名数组a和b:int a[100] , b[100] ; 数组空间大开小用。

调用两次input()函数:分别将两个文本文件data1.txt和data2.txt中已按递增顺序排列好的两个整数序列读入数组a和b中,并返回两个数组中有效元素的个数m和n。 ②为动态数组c分配空间:c = new int [ m+n ] ;

③调用combine()函数:完成数组a、b有序合并到数组c的工作。

④调用output()函数:完成将动态数组c中的整数写入文本文件mydata.txt中的工作。 ⑤释放动态数组c的空间。 ●程序运行前的准备工作:先用记事本建立两个用于存放原始数据的文本文件data1.txt和data2.txt,并输入一些按递增顺序排列好整数,整数之间以若干空格、或者回车换行间隔。例如:

data1.txt:-23 -17 56 67 88

123 187 256 667 886 999

data2.txt:-323 -217 -56 567 887

923 987 2256 6676 8186 9999 56789 66666

●程序运行后的核对工作:使用记事本打开所生成的文本文件mydata.txt,核对文件内容是否正确。 【面向过程程序的参考答案】 # include< fstream.h > # include< iostream.h > # include< iomanip.h >

//定义函数input(),完成将指定文件中的数据全部读入一个数组的工作 int input ( char *filename , int *p , int max ) { ifstream fin ( filename ) ; //打开指定的输入文件

if ( ! fin ) { cout<< filename <<”文件不存在\\n” ; return 0 ; } //打开失败 int temp , count = 0 ;

while ( ! fin.eof() && count<=max ) //未到达流结尾,则进入循环体

2

{ fin >> temp ;

if ( fin. eof( ) == 0 ) p[ count++ ]= temp ; //若读到整数,则放入数组中 }

fin. close( ) ; //关闭输入文件 return count ; }

//定义函数combine(),完成数组a、b有序合并到数组c的工作

void combine ( int *a, int m, int *b, int n , int *c ) { int pa=0 , pb=0 , pc=0 ; while ( pa

if ( a[ pa ] <= b[ pb ] ) c[ pc++ ] = a[ pa++ ] ; else c[ pc++ ] = b[ pb++ ] ;

if ( pa==m ) while ( pb

//定义函数output(),完成将一个数组中的整数写入指定文件的工作 void output ( char *filename , int *p , int k ) { ofstream fout ( filename ) ; //打开指定的输出文件 for ( int i=0; i

if ( (i+1)%4 == 0 ) fout << endl ; } fout << endl ;

fout. close( ) ; //关闭输出文件 return ; }

//定义函数show(),完成将一个数组中的整数显示输出的工作 void show ( int *p , int mnk ) { for ( int i=0; i

if ( (i+1)%4 == 0 ) cout << endl ; } cout << endl ; return ; }

//主函数

void main ( )

{ int a[100] , b[100] ; int m , n , k ;

m = input ( “data1.txt”, a, 100 ) ; n = input ( “data2.txt”, b, 100 ) ; k = m+n ;

int *c = new int [ k ] ;

combine ( a, m, b, n, c ) ; output ( “mydata.txt”, c, k ) ; cout << “数组a中的数据为:\\n” ; show ( a, m ) ;

3

cout << “数组b中的数据为:\\n” ; show ( b, n ) ;

cout << “数组c中的数据为:\\n” ; show ( c, k ) ; delete [ ] c ; }

6.编写面向对象的程序实现以下工作:将存放在两个文本文件(data1.txt、data2.txt)中已按递增顺序排列好的两个整数序列(两个文件中的整数个数不祥,但已按递增顺序排列好),进行合并统一递增排序后写入另一个文本文件mydata.txt中(按每行4个整数的格式),而原始数据文件data1.txt和data2.txt中的内容保持不变。 【面向对象程序的算法提示】

●定义“数组合并类Comb”,要求:

①在构造函数中:分别打开文本文件data1.txt和data2.txt,将各自中的整数序列分别读入到成员数组a和成员数组b中。再分别统计出数组a和数组b中有效元素的个数,并赋给成员m和成员n 。成员k=m+n 。动态建立数组c的空间 c = new int [ k ]。然后调用成员函数combine(),实现成员数组a、b有序合并到动态数组c中。

②在析构函数中:先将动态数组c中的整数依次写入到文本文件mydata.txt中,按每行4个整数的格式写入,然后关闭文本文件mydata.txt,最后再释放动态数组c。 ★私有成员数据:

int a[100] , b[100] ; //两个命名数组a和b,数组空间大开小用。 int *c ; //动态数组c空间的起始地址。

int m , n , k ; //m、n、k分别为a、b、c三个数组中有效元素的个数。 fstream datafile ; //输入输出文件流 ★公有成员函数:

Comb ( ) ; //构造函数 ~ Comb ( ) ; //析构函数

void combine ( ) ; //成员数组a、b有序合并到动态数组c中

void show ( ) ; //显示输出a、b、c三个数组中的元素,每行输出4个整数。 ●编写 main( ) 函数:

使用“合并数组类Comb”定义对象: Comb abc ; ●程序运行前的准备工作:先用记事本建立两个用于存放原始数据的文本文件data1.txt和data2.txt,并输入一些按递增顺序排列好整数,整数之间以若干空格、或者回车换行间隔。例如:

data1.txt:-23 -17 56 67 88

123 187 256 667 886 999

data2.txt:-323 -217 -56 567 887

923 987 2256 6676 8186 9999 56789 66666

●程序运行后的核对工作:使用记事本打开所生成的文本文件mydata.txt,核对文件内容是否正确。 【面向对象程序的参考答案】 # include< fstream > # include< iostream > # include< iomanip >

using namespace std; //数组合并类Comb 的声明 class Comb

{ int a[100] , b[100] ; //两个命名数组a和b,数组空间大开小用。

4

int *c ; //动态数组空间的起始地址

int m , n , k ; //分别是a、b、c三个数组中有效元素的个数 fstream datafile ; //输入输出文件流 public:

Comb ( ) ; //构造函数 ~ Comb ( ) ; //析构函数

void combine ( ) ; //成员数组a、b有序合并到动态数组c中

void show ( ) ; //显示输出a、b、c三个数组中的元素,每行输出4个整数 };

//构造函数

Comb::Comb ( ) { m=0 ; n=0 ; int temp ;

datafile.open ( “data1.txt”, ios::in ) ; //打开输入文件data1.txt if ( ! datafile ) { cout << \打开文件 data1.txt 失败!\\n\ exit( 0 ) ; } while ( ! datafile.eof() ) //若未到达流 datafile 的结尾,则进入循环体 { datafile >> temp ;

if ( datafile. eof( ) == 0 ) a[ m++ ] = temp ; //若读到整数,则放入数组a中 }

datafile. clear( ) ;

//读到流结束符,则跳出while循环,此时流为false,需恢复,因为流还要用。 datafile. close( ) ; //关闭输入文件data1.txt

datafile.open ( “data2.txt”, ios::in ) ; //打开输入文件data2.txt if ( ! datafile ) { cout << \打开文件 data2.txt 失败!\\n\ exit( 0 ) ; } while ( ! datafile.eof() ) //若未到达流 datafile 的结尾,则进入循环体 { datafile >> temp ;

if ( datafile. eof( ) == 0 ) b[ n++ ] = temp ; //若读到整数,则放入数组b中 }

datafile. clear( ) ;

//读到流结束符,则跳出while循环,此时流为false,需恢复,因为流还要用。 datafile. close( ) ; //关闭输入文件data2.txt k = m+n ;

c = new int [ k ] ; //为动态数组c分配存储空间

combine( ) ; //实现成员数组a、b有序合并到动态数组c中 }

//析构函数

Comb::~Comb ( )

{ datafile. open ( “mydata.txt” , ios::out ) ; //打开输出文件mydata.txt for ( int i=0 ; i

if ( (i+1)%4 == 0 ) datafile << endl ; } datafile << endl ;

datafile. close( ) ; //关闭输出文件mydata.txt delete [ ] c ; //释放动态数组c的空间 }

5

本文来源:https://www.bwwdw.com/article/2vu2.html

Top