PAGE
27
第九章 流类库和输入/输出习题
第九章 流类库和输入/输出习题
1. 本概念与基础知识测试题
9.1 填空题
9.1.1 在C++中“流”是表示 (1) 。从流中取得数据称为 (2) ,用符号 (3) 表示;向流中添加数据称为 (4) ,用符号 (5) 表示。
答案:(1)数据从一个对象到另一个对象的传送
(2)提取操作
(3)>>
(4)插入操作
(5)<<
9.1.2 抽象类模板 (1) 是所有基本流类的基类,它有一个保护访问限制的指针指向类(2) ,其作用是管理一个流的 (3) 。C++流类库定义的cin,cout,cerr和clog是 (4) 。cin通过重载 (5) 执行输入,而cout,cerr和clog通过 (6) 执行输出。
答案:(1)basic_ios
(2)basic_streambuf
(3)缓冲区
(4)全局流对象
(5)>>(stream_extraction operator)
(6)<<(stream_insertion operator)
9.1.3 C++在类ios中定义了输入输出格式控制符,它是一个 (1) 。该类型中的每一个量对应两个字节数据的一位,每一个位代表一种控制,如要取多种控制时可用 (2) 运算符来合成,放在一个 (3) 访问限制的 (4) 数中。所以这些格式控制符必须通过类ios的 (5) 来访问。
答案:(1)公有的无名的枚举类型
(2)或“|”
(3)保护
(4)一个长整型数
(5)公共接口(函数)
9.1.4 取代麻烦的流格式控制成员函数,可采用 (1) ,其中有
参数
转速和进给参数表a氧化沟运行参数高温蒸汽处理医疗废物pid参数自整定算法口腔医院集中消毒供应
的,必须要求包含 (2) 头文件。
答案:(1)流操作子
(2)iomanip
9.1.5 通常标准设备输入指 (1) 。标准设备输出指 (2) 。
答案:(1)键盘
(2)显示屏
9.1.6 EOF为 (1) 标志,在iostream.h中定义EOF为 (2) ,在int get()函数中读入表明输入流结束标志 (3) ,函数返回 (4) 。
答案:(1)文件结束标志
(2)-1
(3)^Z(Ctrl-Z)
(4)EOF
9.1.7 C++根据文件内容的 (1) 可分为两类 (2) 和 (3) ,前者存取的最小信息单位为 (4) ,后者为 (5) 。
答案:(1)数据格式
(2)文本文件
(3)二进制文件
(4)字符
(5)字节
9.1.8 当系统需要读入数据时是从 (1) 文件读入,即 (2) 操作。而系统要写数据时,是写到 (3) 文件中,即 (4) 操作。
答案:(1)输入
(2)提取
(3)输出
(4)插入
9.1.9 在面向对象的程序设计中,C++数据存入文件称作 (1) ,而由文件获得数据称作 (2) 。按常规前者往往放在 (3) 函数中,而后者放在 (4) 函数中。
答案:(1)把对象存入文件
(2)由文件重构对象
(3)析构函数
(4)构造函数
9.1.10 文件的读写可以是随机的,意思是 (1) ,也可以是顺序的,意思是 (2) 或 (3) 。
答案:(1)可以从文件任何位置进行读写
(2)从文件头开始
(3)从尾部续上
9.1.11 C++把每一个文件都看成一个 (1) 流,并以 (2) 结束。对文件读写实际上受到 (3) 指针的控制,输入流的指针也称为 (4) ,每一次提取从该指针所指位置开始。输出流的指针也称为 (5) ,每一次插入也从该指针所指位置开始。每次操作后自动将指针向文件尾移动。如果能任意向前向后移动该指针,则可实现 (6) 。
答案:(1)有序的字节
(2)文件结束符(end of file marker)
(3)文件定位
(4)读指针
(5)写指针
(6)随机读写
9.2 简答题
9.2.1 因cin为缓冲流,当键盘一次输入数据过多,保存在缓冲区中了,但这些数据可能是错的,希望清空它,以便下一次要求输入时,按提示正确输入,应该怎样办?
答:只能读空缓冲区。
9.2.2 流状态标志字state各位代表了什么?怎样使用?
答:全0,goodbit=0x00,流正常
第1位为1,eofbit=0x01,输入流结束,忽略后继提取操作;或文件结束,已无数据可取
第2位为1,failbit=0x02,最近的I/O操作失败,流可恢复
第3位为1,badbit=0x04,最近的I/O操作非法,流可恢复
第4位为1,hardfail=0x08,I/O出现致命错误,流不可恢复,VC++6.0不支持
采用成员函数进行操作:
int ios::rdstate() const {return state;} //读取状态字
int ios:operator!() const{return state&(badbit|failbit);} //可用操作符!()代替fail()
int ios::bad(){ return state & badbit;} //返回非法操作位
void ios::clear(int _i){ lock();state=_i;unlock();} //人工设置状态,可用来清状态
int ios::eof() const {return state&eofbit;} //返回流(文件)结束位
int ios::fail() const{return state&(badbit|failbit);} //返回操作非法和操作失败这两位
int ios::good() const{return state==0;} //正常返回1,否则返回0
9.2.3 为什么cin输入时,空格和回车无法读入?这时可改用哪些流成员函数?
答:因为空格和回车都可以作为数据之间的分格符,当输入串时空格和回车无法读入。可改用cin.get()和cin.getline()等流成员函数。
9.2.4 在用cin输入结束时键入^Z,则程序对以后的输入怎样处理?如果要求恢复正常,应执行什么成员函数?
答:不再理会以后的所有输入。可执行成员函数:cin.clear(0); 使流恢复正常
9.2.5 当输出字符串数组名时,输出的是串内容,有何办法可以输出串的首地址?
答:将字符指针强制转换为泛型指针可以输出字符串地址
9.2.6 文件的使用,有它的固定格式,请做简单介绍。
答:
1.说明一个文件流对象,又被称为内部文件,如:
fstream iofile;
2.用文件流对象的成员函数打开一个磁盘文件。打开文件的成员函数的第一个参数为要打开的磁盘文件名。第二个参数为打开方式,有输入(in),输出(out)等,打开方式在ios基类中定义为枚举类型。如:
iofile.open(“myfile.txt”,ios::in|ios::out);
1,2两步可合成如下:
fstream iofile(”myfile.txt”,ios::in|ios::out);
3.使用提取和插入运算符对文件进行读写操作,或使用成员函数进行读写。
4.关闭文件。当打开一个文件进行读写后,应该显式地关闭该文件如:
iofile.close();
9.2.7 在ios类中定义的文件打开方式中,公有枚举类型open_mode的各成员代表什么文件打开方式?
答:in=0x01, //打开文件用于输入操作(从文件读取),如文件不存在则返回失败
out=0x02, //打开文件用于输出操作(写入文件) (缺省方式)
//如文件存在,未同时设app,ate,in则文件清空
ate=0x04,
//打开文件用于输入/输出,文件指针在文件尾,但新数据可写到任何位置
app=0x08, //打开文件用于输出,但从尾部添加,新数据只能添加在尾部
trunce=0x10, //打开文件,并清空它,不存在则建立新文件
binary=0x80 //以二进制方式打开文件
9.2.8 文本文件可以按行也可以按字符进行拷贝,在使用中为保证完整地拷贝各要注意哪些问题?
答:按字符进行拷贝首先必须设置关闭跳过空白(如:iofile.unsetf(ios::skipws)),因为提取(“>>”)运算符在缺省情况下是跳过空白(包括空格,制表,backspace和回车等)的,这样拷贝的文件会缺少一些字符。第二,该程序应能确定文件是否拷贝结束。
按行进行拷贝,getline()回车换行符并不放在buf中,因此要加一个回车换行符。
9.2.9 对文件流,“!”运算符完成什么功能?
答:返回状态字state操作非法和操作失败这两位。
9.2.10 二进制文件读函数read()能否知道文件是否结束?应怎样判断文件结束?
答:读函数并不能知道文件是否结束,可用状态函数int ios::eof()来判断文件是否结束。必须指出系统是根据当前操作的实际情况设置状态位,如需根据状态位来判断下一步的操作,必须在一次操作后立即去调取状态位,以判断本次操作是否有效。
9.2.11 由二进制文件和文本文件来保存对象各有什么优点和缺点?
答:使用二进制文件,可以控制字节长度,读写数据时不会出现二义性,可靠性高。同时不知格式是无法读取的,保密性好。文件结束后,系统不会再读(见eofbit的说明),但程序不会自动停下来,所以要判断文件中是否已没有数据。
使用文本文件来保存对象,操作简单,但谁都可以读取这些数据,无保密性。
9.2.12 文件的随机访问为什么总是用二进制文件,而不用文本文件?
答:在C++中可以由程序来实现文件指针的移动,从而实现文件的随机访问,即可读写流中任意一段内容。一般文本文件很难准确定位,所以随机访问多用于二进制文件。
9.2.13 怎样使用istream和ostream的成员函数来实现随机访问文件?
答:在ios类中说明了一个公有枚举类型:
enum seek_dir{
beg=0,//文件开头
cur=1,//文件指针的当前位置
end=2//文件结尾
};
istream类中提供了如下三个成员函数:
istream&istream::seekg(streampos);//指针直接定位
istream&istream::seekg(streamoff, ios::seek_dir);//指针相对定位
long istream::tellg();//返回当前指针位置
seekg(streamoff,ios::seek_dir)应用最广,如:
datafile.seekg(-20L,ios::cur);
表示将文件定位指针从当前位置向文件头部方向移20个字节。
datafile.seekg(20L,ios::beg);
表示将文件定位指针从文件头向文件尾方向移20个字节。
datafile.seekg(-20L,ios::end);
表示将文件定位指针从文件尾向文件头方向移20个字节。
tellg()和seekg()往往配合使用。
ostream类也提供了三个成员函数管理文件定位指针,它们是:
ostream&ostream::seekp(streampos);
ostream&ostream::seekp(streamoff,ios::seek_dir);
long ostream::tellp();
定位指针只有一个但函数有两组,这两组个函数功能完全一样。
2. 编程与综合练习题
9.3 编程实现以下数据输入输出:
a) 以左对齐方式输出整数,域宽为12;
b) 以八进制、十进制、十六进制输入输出整数;
c) 实现浮点数的指数格式和定点格式的输入输出,并指定精度;
d) 把字符串读入字符型数组变量中,从键盘输入,要求输入串的空格也全部读入,以回车换行符结束;
e) 以上要求用流成员函数和流操作子各做一遍。
解:特别注意flags()和setf()的使用
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
。注意注释。
#include
#include
using namespace std;
int main(void){
int inum1=255,inum2=8191,inum3=65535;
double fnum=31.415926535,fnum1;
char str[255];
cout<<"以左对齐方式输出整数,域宽为12:"<>fnum1;//输入3.1415926535
cout<
using namespace std;
int main(void){
char ch,str[255];
do{
cout<<"请输入一个字符串:"<>ch;
cin.get();//吸收输入Y or N时留下的回车
}while(!(ch=='Y'||ch=='y'));
cout<<"输入正确:"<>”运算符。
#include
#include
#include
#include
using namespace std;
class student{
int id ; //学号
string name; // 姓名
char sex; // 性别
int age; // 年龄
string address; //家庭地址
float eng, phy, math, electron; //英语,物理,数学和电子学成绩
public:
student(int=0,string="#",char='#',int=0,string="#",float=0,float=0,float=0,float=0);
friend ostream&operator<<(ostream&dest,student&st); //重载插入运算符
friend istream&operator>>(istream&sour,student&st); //重载提取运算符
}; //流类作为形式参数必须是引用
student::student(int i,string n,char s,int a,string add,float en,float ph,float ma,float ele){
id=i;
name=n;
sex=s;
age=a;
address=add;
eng=en; phy=ph; math=ma; electron=ele;
}
ostream&operator<<(ostream&dest,student&st){ //重载插入运算符
dest<>(istream&sour,student&st){ //重载提取运算符
cout<<"请输入学号:"<>st.id;
cout<<"请输入姓名:"<>st.name;
cout<<"请输入性别:"<>st.sex;
cout<<"请输入年龄:"<>st.age;
cout<<"请输入地址:"<>st.address;
cout<<"请输入英语、物理、数学、电子各科成绩:"<>st.eng>>st.phy>>st.math>>st.electron;
return sour;
}
int main(){
student st1,st2(2104105,"陈英",'m',19,"黄山路380号",89,78,90,96);
cin>>st1;
cout<>”运算符,对所有可能的错误都能要求重输。
解:
#include
using namespace std;
class Complex{
double Real,Image;
public:
Complex(double r=0.0, double i=0.0):Real(r),Image(i){};//定义构造函数
//见【例5.7】,这里省略,以节约篇幅
friend ostream&operator<<(ostream&s,const Complex&z);
friend istream&operator>>(istream&s,Complex&a);
}; //流类作为形式参数必须是引用
ostream&operator<<(ostream&s,const Complex &z){
return s<<'('<>(istream&s,Complex &a){//格式为r;r,i;(r);(r,i);整个复数输完才可回车
//容错强,如:sd(fr56cv,s79nml,45)i,78回车 可正确判读为(56,79)
double re=0,im=0;
char c=0;
do{
s>>c;
}while(c!='('&&c!='.'&&!(c>='0'&&c<='9'));//读空括号或数字前的无用字符
if(c=='('){
do{
s>>c;
}while(c!='.'&&!(c>='0'&&c<='9'));//读空数字串前的无用字符
s.putback(c);//返回一个字符到输入缓冲区
s>>re;//实部
do{
s.get(c);//因为可能是回车
}while(c!='\n'&&c!=')'&&c!=',');//读空数字串后的无用字符
if(c==','){
do{//只读数字串
s>>c;
}while(c!='.'&&!(c>='0'&&c<='9'));
s.putback(c);
s>>im;//虚部
do{
s.get(c);//因为可能是回车
}while(c!='\n'&&c!=')');//读空数字串后的无用字符
}
else im=0;//无此步,第二次赋值出错
if(c!=')')s.clear(ios::failbit);//漏了括号给一个操作失败标志
}
else{
s.putback(c);//无括号,返回一个字符到输入缓冲区
s>>re;//实部
do{
s.get(c);//因为可能是回车
}while(c!='\n'&&c!=',');//读空数字串后的无用字符
if(c==','){
do{//只读数字串
s>>c;
}while(c!='.'&&!(c>='0'&&c<='9'));
s.putback(c);
s>>im;//虚部
do{
s.get(c);//因为可能是回车
}while(c!='\n');//读空数字串后的无用字符
}
else im=0;//无此步,第二次赋值出错
}
if(s) a=Complex(re,im);
return s;
}
int main(){
Complex a,b,c,d;
cout<<"输入一个实数"<>a;
cout<<"输入一个复数"<>b;
cout<<"输入一个用括号括起来的实数"<>c;
cout<<"输入一个用括号括起来复数"<>d;
cout<<"a="<
#include //不包含
#include
using namespace std;
int main(){
int line=0;
char filename[256],buf[256];
fstream sfile,dfile;
cout<<"输入源文件路径名:"<>filename;//对路径各方面而言空格是无关紧要的,否则要用getline()等成员函数
sfile.open(filename,ios::in);//打开一个已存在的文件
while(!sfile){
cout<<"源文件找不到,请重新输入路径名:"<>filename;
sfile.open(filename,ios::in);
}
cout<<"输入目标文件路径名:"<>filename; //只能创建文件,不能建立子目录,如路径不存在则失败
dfile.open(filename,ios::out);
if(!dfile){
cout<<"目标文件创建失败"<
#include
#include
using namespace std;
int main(){
int n;
char filename[256],buf[100];
fstream sfile,dfile;
cout<<"输入源文件路径名:"<>filename;//对路径各方面而言空格是无关紧要的,否则要用getline()等成员函数
sfile.open(filename,ios::in|ios::binary);//打开一个已存在的二进制文件
while(!sfile){
cout<<"源文件找不到,请重新输入路径名:"<>filename;
sfile.open(filename,ios::in|ios::binary);
}
cout<<"输入目标文件路径名:"<>filename; //只能创建文件,不能建立子目录,如路径不存在则失败
dfile.open(filename,ios::app|ios::out|ios::binary);//文件指针在尾部
if(!dfile){
cout<<"目标文件创建失败"<
#include
#include
using namespace std;
int main(){
int n;
char filename[256],buf[100];
fstream sfile,dfile;
cout<<"输入源文件路径名:"<>filename;//对路径各方面而言空格是无关紧要的,否则要用getline()等成员函数
sfile.open(filename,ios::in|ios::binary);//打开一个已存在的二进制文件
while(!sfile){
cout<<"源文件找不到,请重新输入路径名:"<>filename;
sfile.open(filename,ios::in|ios::binary);
}
cout<<"输入目标文件路径名:"<>filename; //只能创建文件,不能建立子目录,如路径不存在则失败
dfile.open(filename,ios::in|ios::out|ios::binary); //打开输入输出文件
if(!dfile){
dfile.clear(0);
dfile.open(filename,ios::out); //建立输出文件
dfile.close();
dfile.open(filename,ios::in|ios::out|ios::binary); //改为输入输出文件
}
dfile.seekp(0,ios::end);//写指针重定位到文件尾, seekp和seekg是同一个文件指针
while(!sfile.eof()){//二进制方式需另判文件是否结束 A
sfile.read(buf,100);
n=sfile.gcount();
dfile.write(buf,n);//按实际读取字节数写
}
sfile.close();
dfile.close();
return 0;
}
9.10 采用筛选法求100以内的所有素数(参见【例3.16】)。将所得数据存入文本文件和二进制文件。对送入文本文件中的素数,要求存放格式是每行10个素数,每个数占6个字符,左对齐;可用任一文本编辑器将它打开阅读。二进制文件整型数的长度请用sizeof()来获得,要求可以正序读出,也可以逆序读出(利用文件定位指针移动实现),读出数据按文本文件中的格式输出显示。
解:前半题文本文件与习题3.17相同,只是那里是右对齐,这里只新做了二进制文件。注意逆序输出前,试读看有多少数据时,一旦读到文件结束,eofbit=1,不清0,后面操作不能进行。
#include
#include
#include
const int n=100;
void main(){
ofstream ofile;
ifstream ifile;
int a[n],i,j;
char ch,b[256];
for(i=0;i>ch;
if(ch=='y'||ch=='Y'){
ifile.open("myfile9_9.txt");
i=0;
while(ifile.get(b[i])){//读标题,不可用>>,它不能读白字符,
if(b[i]=='\n') break;
i++;
}
b[i]='\0';
cout.flags(ios::left);
cout<>i;//由文件读入
if(ifile.eof()!=0) break;
cout<>ch;
if(ch=='y'||ch=='Y'){
count=0;
ifile.open("myfile9_9.dat",ios::in|ios::binary);
while(1){
ifile.read((char*)&i,sizeof(int));
if(ifile.eof()!=0) break;
cout<>ch;
if(ch=='y'||ch=='Y'){
count=0;
ifile.open("myfile9_9.dat",ios::in|ios::binary);
while(1){
ifile.read((char*)&i,sizeof(int));
if(ifile.eof()!=0) break;
count++;
}
ifile.clear(0);//当文件读完时,eofbit=1,不清0,后面的操作不能进行
ifile.seekg(-4,ios::end);
for(j=1;j<=count;j++){
ifile.read((char*)&i,sizeof(int));
cout<
#include
#include
#include
using namespace std;
class sinx{
double Degree;//角度
double Value;//正弦值
public:
sinx(double =0);
void display();
void Bdatatofile(fstream &); //文件流类作为形式参数必须是引用
void Bdatafromfile(fstream &);
void datainput(double deg);
bool operator<=(sinx &);
bool operator==(sinx &);
};
bool sinx::operator<=(sinx & si){
double k;
k=Degree-si.Degree;
if(k<=0) return true;
else return false;
}
bool sinx::operator==(sinx & si){
double k;
k=Degree-si.Degree;
if(k==0) return true;
else return false;
}
sinx::sinx(double deg){
Degree=deg;
Value=sin(deg*3.1415926535/180);
}
void sinx::display(){
cout<class Array{
T *elements;
char name[20];
int Subscript;//已用最大下标值
int maxSize;
fstream datafile;
public:
Array(char* ="myfile",int=20);
~Array();
bool IsFull() const{return Subscript==maxSize-1;}
void renews();//数组扩大一倍
void ordinsert(T&);//升序输入
void listshow();//显示数组
};
template Array::Array(char* filename,int maxs){
maxSize=maxs;
Subscript=-1;//私有数据不容许直接赋初值,必须在构造函数中赋初值
strcpy(name,filename);
T temp;
elements=new T[maxSize];
datafile.open(name,ios::binary|ios::in);
if(!datafile==0){
while(!datafile.eof()){
temp.Bdatafromfile(datafile);
//
datafile.read((char*)&temp,sizeof(T));//直接读写法与使用成员函数结果相同
if(datafile.eof()==0){//读到无数据可读后,即读入不成功,eofbit为1
ordinsert(temp);
}
}
datafile.close();
}
datafile.clear(0);//采用标准库不可少,前面读到过文件结束或打开文件失败,无法恢复
}
template Array::~Array(){
int i;
datafile.open(name,ios::binary|ios::out);
for(i=0;i<=Subscript;i++)
elements[i].Bdatatofile(datafile);
//
datafile.write((char*)&elements[i],sizeof(T));//直接读写法与使用成员函数结果相同
datafile.close();
delete[]elements;
}
template void Array::renews(){
int i;
T *temp=elements;
maxSize*=2;
elements=new T[maxSize];
for(i=0;i<=Subscript;i++) elements[i]=temp[i];
delete[]temp;
}
template void Array::ordinsert(T & elem){//以角度为关键字排序
int i,j;
if(IsFull()) renews();
for(i=0;i<=Subscript;i++) if(elem<=elements[i]) break;
if(!(elem==elements[i])){
for(j=Subscript;j>=i;j--) elements[j+1]=elements[j];
Subscript++;
}
if(Subscript==-1) Subscript++;//考虑到进入的第一项
elements[i]=elem;
}
template void Array::listshow(){
int i;
for(i=0;i<=Subscript;i++) elements[i].display();
}
//两个文件归并用独立的函数模板
template void Merge(char*filename1,char*filename2,char*filename){
fstream sdatafile1(filename1,ios::out|ios::in|ios::binary);
fstream sdatafile2(filename2,ios::out|ios::in|ios::binary);
fstream ddatafile(filename,ios::out|ios::binary);
int i=0,j=0,k=0,ns1,ns2;
T temps1,temps2;
while(sdatafile1.eof()==0){//侧元素数量,注意会多出一个
sdatafile1.read((char*)&temps1,sizeof(T));
i++;
}
ns1=i-1;
cout<<"表1元素数"< mylist("mydata1");
cout<<"建立正弦表1(0,2,4,~80度)"< mylist("mydata2");
cout<<"建立正弦表2(1,3,5,~81度;82,83,~90)"<("mydata1","mydata2","mydata");//按题意要求两个文件归并直接使用文件
Array mylist("mydata");
cout<<"输出正弦表(0,1,~90度)"<
#include
#include
#include
using namespace std;
class sinx{
double Degree;//角度
double Value;//正弦值
public:
sinx(double =0);
void display();
void datainput(double deg);
bool operator<=(sinx &);
bool operator==(sinx &);
};
bool sinx::operator<=(sinx & si){
double k;
k=Degree-si.Degree;
if(k<=0) return true;
else return false;
}
bool sinx::operator==(sinx & si){
double k;
k=Degree-si.Degree;
if(k==0) return true;
else return false;
}
sinx::sinx(double deg){
Degree=deg;
Value=sin(deg*3.1415926535/180);
}
void sinx::display(){
cout< void listshow(T*elements,int subsc){
int i;
for(i=0;i<=subsc;i++) elements[i].display();
}
template void ordinsert(T & elem,T*elements,int subsc){//以角度为关键字排序
int i,j;
for(i=0;i<=subsc-1;i++) if(elem<=elements[i]) break;
if(!(elem==elements[i])){
for(j=subsc-1;j>=i;j--) elements[j+1]=elements[j];
}
elements[i]=elem;
}
template int readfile(char* filename,T*elements){//文件写入链表,返回最大下标
int k=-1;
T temp;
ifstream datafile;
datafile.open(filename,ios::binary|ios::in);
while(!datafile.eof()){
datafile.read((char*)&temp,sizeof(T));
if(datafile.eof()==0){//读到无数据可读后,即读入不成功,eofbit为1
k++;
ordinsert(temp,elements,k);
}
}
datafile.close();
return k;
}
template void writefile(char* filename,T*elements,int subsc){
int i;
ofstream datafile;
datafile.open(filename,ios::binary|ios::out);
for(i=0;i<=subsc;i++)
datafile.write((char*)&elements[i],sizeof(T));
datafile.close();
}
//两个文件归并用独立的函数模板
template void Merge(char*filename1,char*filename2,char*filename){
fstream sdatafile1(filename1,ios::out|ios::in|ios::binary);
fstream sdatafile2(filename2,ios::out|ios::in|ios::binary);
fstream ddatafile(filename,ios::out|ios::binary);
int i=0,j=0,k=0,ns1,ns2;
T temps1,temps2;
while(sdatafile1.eof()==0){//求文件所含数据数量
sdatafile1.read((char*)&temps1,sizeof(T));
i++;
}
ns1=i-1;
while(sdatafile2.eof()==0){
sdatafile2.read((char*)&temps2,sizeof(T));
j++;
}
ns2=j-1;
sdatafile1.clear(0);
sdatafile2.clear(0);
i=0;
j=0;
sdatafile1.seekg(0,ios::beg);
sdatafile2.seekg(0,ios::beg);
sdatafile1.read((char*)&temps1,sizeof(T));//此方法与用成员函数完全相同
sdatafile2.read((char*)&temps2,sizeof(T));//对于类对象,读和写及大小均仅指数据成员
while(i("mydata1","mydata2","mydata");//按题意要求两个文件归并直接使用文件
cout<<"输出正弦表(0,1,~90度)"<
#include
#include
#include
using namespace std;
class student{
int id ; //学号
string name; // 姓名
char sex; // 性别
int age; // 年龄
string address; //家庭地址
float eng, phy, math, electron; //英语,物理,数学和电子学成绩
public:
student(int=0,string="#",char='#',int=0,string="#",float=0,float=0,float=0,float=0);
void Bdatatofile(fstream & dest); //数据写入文件流类
void Bdatafromfile(fstream & sour); //由文件流类读出数据
bool operator<=(student &ele){return id<=ele.id;}
bool operator==(student &ele){return id==ele.id;}
friend ostream&operator<<(ostream&dest,student&st); //重载插入运算符
friend istream&operator>>(istream&sour,student&st); //重载提取运算符
};
student::student(int i,string n,char s,int a,string add,float en,float ph,float ma,float ele){
id=i;
name=n;
sex=s;
age=a;
address=add;
eng=en; phy=ph; math=ma; electron=ele;
}
void student::Bdatatofile(fstream & dest){ //文件流类作为形式参数必须是引用
dest.write((char*)&id,sizeof(int));
dest.write(name.c_str(),20);//由string类的c_str()函数转为char*
dest.write((char*)&sex,sizeof(char));
dest.write((char*)&age,sizeof(int));
dest.write(address.c_str(),20);//由string类的c_str()函数转为char*
dest.write((char*)&eng,sizeof(float));
dest.write((char*)&phy,sizeof(float));
dest.write((char*)&math,sizeof(float));
dest.write((char*)&electron,sizeof(float));
}
void student::Bdatafromfile(fstream & sour){ //文件流类作为形式参数必须是引用
char Desc[20];
sour.read((char*)&id,sizeof(int));
sour.read(Desc,20);//必须由字符数组过渡
name=Desc;
sour.read((char*)&sex,sizeof(char));
sour.read((char*)&age,sizeof(int));
sour.read(Desc,20);//必须由字符数组过渡
address=Desc;
sour.read((char*)&eng,sizeof(float));
sour.read((char*)&phy,sizeof(float));
sour.read((char*)&math,sizeof(float));
sour.read((char*)&electron,sizeof(float));
}//由此可见读和写是完全对称的过程,次序决不能错
ostream&operator<<(ostream&dest,student&st){ //文件流类作为形式参数必须是引用
dest<>(istream&sour,student&st){ //文件流类作为形式参数必须是引用
cout<<"请输入学号:"<>st.id;
cout<<"请输入姓名:"<>st.name;
cout<<"请输入性别:"<>st.sex;
cout<<"请输入年龄:"<>st.age;
cout<<"请输入地址:"<>st.address;
cout<<"请输入英语、物理、数学、电子各科成绩:"<>st.eng>>st.phy>>st.math>>st.electron;
return sour;
}
template class Array{
T *elements;
int Subscript; //已用最大下标值
int maxSize;
fstream datafile;
public:
Array(int=3); //为了便于检验,缺省元素数暂为3
~Array();
bool IsFull() const{return Subscript==maxSize-1;}
void renews(); //内存扩大一倍
void show(){
cout<<"已用最大下标值"< Array::Array(int maxs){
maxSize=maxs;
Subscript=-1; //私有数据不容许直接赋初值,必须在构造函数中赋初值
T temp;
elements=new T[maxSize];
datafile.open("mydatafile.dat",ios::binary|ios::in); //如文件不存在,打开失败
if(!datafile==0){
while(!datafile.eof()){
temp.Bdatafromfile(datafile);
if(datafile.eof()==0){ //读到无数据可读后,即读入不成功,eofbit为1
ordinsert(temp); //即使原文件未排序,退出时按排好序的重存
}
}
datafile.close(); //必须放此处,打开成功才能关闭
}
datafile.clear(0); //前面曾经读到文件结束或文件打开失败,流无法恢复
}
template Array::~Array(){
int i;
datafile.open("mydatafile.dat",ios::binary|ios::out);
for(i=0;i<=Subscript;i++) elements[i].Bdatatofile(datafile);
datafile.close();
delete[]elements;
}
template void Array::renews(){
int i;
T *temp=elements;
maxSize*=2;
elements=new T[maxSize];
for(i=0;i<=Subscript;i++) elements[i]=temp[i];
delete[]temp;
}
template void Array::ordinsert(T & elem){ //输入时以学号为关键字排序
int i,j;
if(IsFull()) renews();
for(i=0;i<=Subscript;i++) if(elem<=elements[i]) break;
if(!(elem==elements[i])){
for(j=Subscript;j>=i;j--) elements[j+1]=elements[j];
Subscript++;
}
elements[i]=elem;
show();
}
template ostream&operator<<(ostream&dest,Array&ar){
int i;
for(i=0;i<=ar.Subscript;i++) cout< mylist;
student temp;
char ch;
cout<<"是否输入新学生信息?Y or N"<>ch;
while(ch=='Y'||ch=='y'){
cin.get();//吸收回车
cin>>temp;
mylist.ordinsert(temp);
cout<<"是否继续输入?Y or N"<>ch;
}
cout<
本文档为【vc++习题答案C++第九章习题解答】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。