输入输出流类_第1页
输入输出流类_第2页
输入输出流类_第3页
输入输出流类_第4页
输入输出流类_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

输入输出流类第1页,课件共42页,创作于2023年2月

外部设备可分为人机交互设备和存储设备两个大类。 人机交互设备主要指键盘、显示器等终端控制台设备和打印机。 存储设备指磁带、磁(软、硬)盘、光盘等以文件形式存储持久数据的设备。

第2页,课件共42页,创作于2023年2月 早期程序设计语言中通常以文件方式来统一人机交互设备和存储设备的输入输出操作。即将人机交互设备当作一种特殊文件对待。 以文件方式统一管理外部设备可以屏蔽实际物理设备的差异,有利于整体上简化程序设计语言与外部设备交换信息的处理过程。第3页,课件共42页,创作于2023年2月

C++语言对输入输出的处理引入了“流”这个比文件抽象程度更高的概念。输入输出操作被看作数据在源设备对象与目标设备对象之间的流动。

C++中完成输入输出操作的类称为流类,并提供了可重用的流类库。第4页,课件共42页,创作于2023年2月11.1C++流库结构 标准ANSIC程序中的绝大部分工作是由ANSIC标准库中的printf,scanf完成的,I/O功能作为ANSIC标准库功能的一部分被提供。在C++中iostream库提供了printf、scanf功能的替代方法,输入输出功能的实现由一个iostream对象完成。第5页,课件共42页,创作于2023年2月1.

流缓冲区类在C++I/O类库定义文件iostream.h中有一个streambuf类,它用来提供物理设备的接口。缓冲区由一段预留的字符存储空间和两个指针组成,两个指针分别指向字符要被插入或被取出的位置。streambuf类定义了一组缓冲或处理流的通用方法,诸如设置缓冲区,移动指针,存、取字符等。

conbufstrstreambuffilebufstreambuf图11.1流缓冲区类的派生关系C++I/O流类的结构(1)第6页,课件共42页,创作于2023年2月streambuf类有三个派生类,其中:

(1)

conbuf在constream.h中定义,提供光标控制、清屏,定义活动窗口等控制台操作接口和I/O缓冲区管理功能。(2)

filebuf在fstream.h中定义,它用来维护文件缓冲区的打开,关闭,读、写,建立磁盘文件的内存代理。(3)

strstreambuf在strstream.h中定义,提供在内存进行提取和插入操作的缓冲区管理。第7页,课件共42页,创作于2023年2月2.

输入输出流类

iostream.h中还有以ios类为基类的一组流类的定义。

ios类及其派生类均含有一个指向streambuf类的指针。通过streambuf类代理物理设备的操作。 从类ios开始,逐级派生,形成了较为复杂的结构,要很好地使用C++流类,必须逐级了解其父类的public、和protected类型的成员函数、成员变量。第8页,课件共42页,创作于2023年2月istream_withassignostream_withassignstrstreambaseifstreamistrstreamofstreamostrstreamfstreamstrstreamiostreamiostream_withassignistreamostreamfstreambaseios图11.2ios类的派生关系C++I/O流类的结构(2)第9页,课件共42页,创作于2023年2月流类分类流类名称流类作用流基础类ios所有流类的父类、保存流的状态并处理错误输入流类istream输入流基础类、将流缓冲区中的字符作格式化和非格式化之间的转换,并输入。ifstream文件输入流类istream_withassign为cin输入流类即操作符>>输入流istrstream串输入流类输出流类ostream输出流的基础类、将流缓冲区中的数据格式化或非格式化转换,并输出。ofstream文件输出流类ostream_withassigncout,cerr,clog输出的流类即操作符<<输出流。ostrstream串输出流类文件流类fstreambase文件流基础类串流strstreambase串流基础类输入/输出流类iostream多目的输入/输出流类的基础类fstream文件流输入/输出类strstream串流输入/输出类流类库成员列表第10页,课件共42页,创作于2023年2月上表中:(1)基础类ios是所有流类的根。它有四个直接派生类:istream、ostream、fstreambase和strstreambase,它们是流类库中的基本流类。(2)istream和ostream是ios直接派生类,其功能是将数据格式化或非格式化数据与流缓冲区之间作转换处理。(3)istream_withassign,ostream_withassign分别从istream和ostream类派生,并定义了cin,cout流,作标准输入和输出处理。(4)而iostream是istream和ostream类的多继承派生类,用来操作文件流的标准输入/输出。(5)ifstream是istream和fstreambase的多继承派生类,用于处理文件的输入。(6)ofstream是ostream和fstreambase的多继承派生类,用于处理文件的输出。第11页,课件共42页,创作于2023年2月11.2C++输入与输出

输入输出流可以从文件或设备中读出或写入数据,C++运行库提供了两种输入输出功能。

(1)类输入/输出,把数据作为单字符流处理。可以处理简单的数据,也可以处理复杂的数据结构。 (2)直接调用操作系统的底层功能实现输入/输出操作。

每一类都有文件和标准的输入和输出功能。这里着重讨论使用流类的标准输入和输出,以及流类的文件输入和输出。第12页,课件共42页,创作于2023年2月11.2.1标准输入输出 标准输入与输出是指读键盘的数据和将数据输出到屏幕。C++用istream_withassign类和ostream_withsaaign类来实现标准输入输出功能。

iostream.h文件中以下两句定义cin和cout两个标准流对象: istream_withassigncin; ostream_withassigncout;

在标准输入类istream_withassign和标准输出类ostream_withassign分别对操作符“>>”“<<”进行了重载,用于完成对各种简单数据类型的输入和输出。第13页,课件共42页,创作于2023年2月11.2.2格式化的输入输出C++提供了两种格式控制函数用来控制输入输出的格式:ios类中定义的格式控制成员函数基于流对象的操纵函数。相比之下操纵函数使用更为方便。下面重点介绍操纵函数的概念和用法。第14页,课件共42页,创作于2023年2月1.ios类中定义的格式控制标志ios类中定义了一个数据成员:格式控制标志字longx_flags。x_flags每一位的状态值用枚举符号常量定义。enum{skipws=0x0001, //跳过输入空格

left=0x0002, //输出左对齐调整

right=0x0004, //输出右对齐调整

internal=0x0008, //输出符号和基指示符后的填补

dec=0x0010, //转换为十进制(in/out)oct=0x0020, //转换为八进制(in/out)hex=0x0040, //转换为十六进制(in/out)showbase=0x0080, //输出显示基指示符

showpoint=0x0100, //输出显示小数点

uppercase=0x0200, //大写十六进制输出

showpos=0x0400, //正整数显示前加上”+”scientific=0x0800, //输出用科学表示法表示浮点数

fixed=0x1000, //输出用固定小数点表示浮点数

unitbuf=0x2000, //在输出操作后刷新所有流

stdio=0x4000 //在输出后刷新stdout和stderr};第15页,课件共42页,创作于2023年2月longx_flags=0x0080=0000000010000000输出显示基指示符longx_flags=0x0003=0000000000000011跳过输入空格&输出左对齐调整longx_flags=0x0083=0000000010000011跳过输入空格

&输出左对齐调整

&输出显示基指示符longx_flags标志可以由ios类的成员函数flags(),setf()和unsetf()访问,也可以用操纵函数操作。

第16页,课件共42页,创作于2023年2月2.操纵函数和操纵符操纵函数分为带参数和不带参数两种。不带参数的操纵函数又叫操纵符。操纵符定义在头文件iostream.h中,操纵函数定义在头文件iomanip.h中.

第17页,课件共42页,创作于2023年2月表11.2iostream.h中的操纵符

操作符用法举例结果说明dec

cout<<dec<<intvar;cin>>dec>>intvar;将整数转化为十进制格式输出将整数转化为十进制格式输入hexcout<<hex<<intvar;cin>>hex>>intvar;将整数转化为十六进制格式输出将整数转化为十六进制格式输入octcout<<oct<<intvar;cin>>oct>>intvar;将整数转化为八进制格式输出将整数转化为八进制格式输入wscin>>ws;忽略输入流中的空格endlcout>>endl;插入换行符,刷新流endscout>>ends;插入串最后的串结束符flushcout>>flush;刷新一个输入流第18页,课件共42页,创作于2023年2月表11.3iomanip.h中的操纵函数

setprecision(int)cout<<setprecision(6)cin>>setprecision(15)输出浮点数精度为6位小数输入浮点数精度为15位小数setw(int)cout<<setw(6)<<var;cin>>setw(24)>>buf;输出数据宽度为6输入数据宽度为24setiosflags(long)cout<<setioflags(ios::hex|ios::uppercase)cin>>setioflags(ios::oct|ios::skipws)指定数据输出的格式为十六进制格式且用大写字母输出指定数据输入的格式为八进制格式且跳过输入中的空白resetiosflags(long)cout<<resetiosflags(ios::dec)cin>>resetiosflags(ios::hex)取消数据输出的格式为十进制格式取消数据输入的格式为十进制格式第19页,课件共42页,创作于2023年2月例11.1操纵符的使用#include<iostream.h>#include<iomanip.h>voidmain(){doublevalues[]={1.23,35.36,653.7,4358.24};char*names[]={"Zoot","Jimmy","Al","Stan"};cout<<setiosflags(ios::fixed);//浮点数使用普通记数法表示

for(inti=0;i<4;i++)cout<<setiosflags(ios::left)//设置左对齐

<<setw(6)//设置数据宽度为6位

<<names[i]<<resetiosflags(ios::left)//撤消左对齐

<<setw(10)//设置数据宽度为10位

<<setprecision(1)//设置浮点数精度1位

<<values[i]<<endl;}输出为:Zoot1.2Jimmy35.4Al653.7Stan4358.2

第20页,课件共42页,创作于2023年2月11.3流类运算符重载使用传统的C语言中printf,scanf等输入输出函数编写的程序,当输入输出的数据类型发生变化时,必须重写所有的输入输出代码。使用C++流类后,这个问题不复存在。C++利用流类对象cin、cout的成员函数重载任意类的输入输出操作。流的输入运算符”>>”又称提取运算符,流的输出运算符”<<”又称插入运算符,它们都可以重载。第21页,课件共42页,创作于2023年2月例:用户定义的日期Date类的输入输出。

为保持和简单类型的输入输出同样的形式,需要为Date类重载操作符<<和>>。 由于重载的函数需要访问Date类的私有的和受保护的成员,应该把这些重载的函数定义为Date类的友元。第22页,课件共42页,创作于2023年2月#include<iostream.h>classDate{intmo,da,yr;public:Date(intm,intd,inty){mo=m;da=d;yr=y;}friendostream&operator<<(ostream&os,Date&dt);friendistream&operator>>(istream&is,Date&dt);};ostream&operator<<(ostream&os,Date&dt){os<<dt.mo<<'/'<<dt.da<<'/'<<dt.yr;returnos;//返回流的引用}istream&operator>>(istream&is,Date&dt){is>>dt.mo>>dt.da>>dt.yr;returnis;//返回流的引用}voidmain(){intmo,da,yr;Datedt(7,1,1997);cout<<dt<<endl;cin>>mo>>da>>yr;Dateotherdt(mo,da,yr);cout<<otherdt<<endl;Datedt_input(0,0,0);cin>>dt_input;cout<<dt_input<<endl;}例11.2用户定义Date数据类中对流类运算符<<、>>函数重载第23页,课件共42页,创作于2023年2月重载操作符函数时应该注意以下几点:

重载的操作符函数有两个参数。 如果重载的是输出操作符<<,第一个参数是对流ostream类的引用,如果重载的是输入操作符>>,第一个参数是对流istream类的引用。 第二个参数是要定义输入输出类的引用,也可以是此类的指针。

运算符重载必须定义为类的友元,因为左操作数必须是流类对象而不是输入/输出类的对象,不能使用隐式左操作数。

第24页,课件共42页,创作于2023年2月#查询复杂程度复杂数据、有查询对象-关系数据库(ORDB)简单数据、无查询文本文件简单数据、无查询面向对象数据库(OODB)简单数据、有查询关系式数据库(RDB)第25页,课件共42页,创作于2023年2月11.4文件流与文件操作11.4.1C++标准库文件输入与输出标准的C++库提供了文件输入输出功能,它们是以函数的形式给出的。这里将对一些常用的函数如fopen、fclose、fwrite、fread等作简要说明。标准的C库对文件输入输出功能函数定义在stdio.h头文件中,并且定义了一个FILE型文件结构,在每一个文件被打开时,都有一个FILE型文件指针与之关联,以便保存文件的相关信息,完成文件的读写操作。第26页,课件共42页,创作于2023年2月对文件的操作一般分为三个步骤:(1)使用文件打开函数对文件进行打开,并与文件指针建立关系;(2)利用文件指针和写文件、读文件函数对文件进行操作。(3)使用文件关闭函数,对文件关闭。

第27页,课件共42页,创作于2023年2月1打开文件函数fopen完成文件操作第一步,可使用fopen函数,该函数定义为:FILE*fopen(constchar*filename,constchar*mode);其中参数filename是文件名字符串,mode为文件打开的模式。使用时注意:1).返回值是返回打开文件的指针,如果文件不存在或者不能找到文件,fopen调用返回空指针(NULL)表示为文件打开失败。

2).参数mode可取以下值"r"

只读方式打开文件。"w"写方式打开文件,如果文件已经存在,其文件中的内容被破坏。"r+"

读和写的方式打开。(文件必须已经存在,否则将导致异常)"

w+"读和写方式打开一空文件,如果该文件已经存在,其内容将被破坏。"

a+"为了读文件和附加新内容而打开文件。"

t"

以文本方式打开文件。"

b"

二进制的方式打开文件。第28页,课件共42页,创作于2023年2月2.文件读写函数fread和fwrite

完成第二步操作,就是要对文件进行读和写数据,一般常用fread读文件函数和fwrite函数,函数的使用格式为:

size_tfread(void*buffer,size_tsize,size_tcount,FILE*stream);size_tfwrite(constvoid*buffer,size_tsize,size_tcount,FILE*stream);使用时注意:(1)fread函数读文件返回文件数据记录的数目;(2)fwrite函数返回实际写入文件数据记录的数目;(3)参数buffer 指向数据缓冲区。fread函数将读出的数据放在缓冲区中供程序使用;fwrite函数将写入文件的数据放在冲区中以便写入文件。(4)size为从文件读出和写入文件的字节数(5)count一次从文件读出数据的最大记录数和一次写入文件的最大记录数。(6)stream文件结构指针。fread函数为打开文件的针;fwrite函数为把数据要写入文件的指针。第29页,课件共42页,创作于2023年2月3关闭文件函数fclose

完成第三步操作可以使用fclose,其格式为:intfclose(FILE*stream);//关闭流文件(fclose)int_fcloseall(void);//关闭所有的流(_fcloseall)

使用时注意:

(1)fclose函数返回值为0时表示文件成功关闭,否则返回值为非0。(2)fcloseall成功关闭所打开的文件时,函数返回值为关闭文件的总数。(3)fclose函数的参数为指向FILE结构体的指针。第30页,课件共42页,创作于2023年2月例11.3打开一个名为

FREAD.OUT的文件并写入25个字符,然后将从文件中读出的字符#include<stdio.h>voidmain(){FILE*stream;charlist[30];inti,numread,numwritten;//文本模式打开文件并写数据

if((stream=fopen("fread.out","w+t"))!=NULL){for(i=0;i<25;i++)list[i]=(char)('z'-i);numwritten=fwrite(list,sizeof(char),25,stream);printf("Wrote%ditems\n",numwritten);fclose(stream);}elseprintf("Problemopeningthefile\n");/*读出25个字符*/if((stream=fopen("fread.out","r+t"))!=NULL){numread=fread(list,sizeof(char),25,stream);printf("Numberofitemsread=%d\n",numread);printf("Contentsofbuffer=%.25s\n",list);fclose(stream);}elseprintf("Filecouldnotbeopened\n");}输出:Wrote25itemsNumberofitemsread=25Contentsofbuffer=zyxwvutsrqponmlkjihgfedcb第31页,课件共42页,创作于2023年2月11.4.2文件输入输出流在C++中,对文件的输入输出操作提供了另一种操作方式,即流类库的文件操作,这些类是ofstream与ifstream文件输入输出流类。其对文件操作也需要上述的三个步骤。1.文件的输出文件的输出由ofstream完成,它由ostream类继承而来(见图11.2),并继承了它的操作,因此可以利用ostream重载的操作符<<把数据写入文件流中。进行文件输出时首先要创建文件输出流ofstream类的一个对象,ofstream类的构造函数用于在不同情况下构造文件流。下面是ofstream类造函数的定义:ofstream();ofstream(constcharFAR*,int=ios::out,int=filebuf::openprot);第32页,课件共42页,创作于2023年2月(1)文件的打开第一个构造函数用于构造一个不带参数的流,如果需要可以在用它的open函数打开一个文件,下面是open函数的定义:voidopen(constsignedchar_FAR*,int=ios::in,int=filebuf::openprot);它需要三个参数,第一个参数为字符串,为打开文件的文件名;第二个参数为文件模式,缺省为ios::out,表示为输入打开,其它文件模式见表11.4;第三个参数为文件的保护方式它们有三种取值0表示普通文件、1表示只读文件、2表示隐含文件、4表示系统文件、8表示文档位格式。例如对打开一个test1.dat文件可用如下语句:

ofstreamafile();afile.open("test1.dat");或afile.open("test1.dat",ios::out|ios::binary)第二个构造函数可以在创建文件时通过第一个参数直接指定文件名。第二个参数、第三个参数同上述open函数。对打开一个test1.dat文件可用如下语句:

ofstreamafile("test1.dat");ofstreamafile("test1",ios::noreplace);ofstreamafile("test1",ios::append);ofstreamafile("test1",ios::out|ios::binary);第33页,课件共42页,创作于2023年2月表11.4

文件模式模式功能说明Ios:app追加数据,总是加在源文件的尾部Ios::ate在打开的文件上找到文件尾Ios::in为输入打开文件(默认对ifstream适用)Ios::out为输出打开文件(默认对ofstream适用)Ios::binary打开二进制文件Ios::trunc如文件存在则消去原内容Ios::nocreate如文件不存在,打开失败Ios::noreplace如文件存在,打开失败,除非设置了ate和app第34页,课件共42页,创作于2023年2月2).文件的写入数据函数ofstream类是从ostream类继承而来,因而可以使用ostream类的写数据的函数和操作符把数据写入文件,操作符函数在前面已经介绍,这里实现写数据的函数是:class_CRTIMPostream:virtualpublicios{……public://写入字符文件

inline ostream&put(char); ostream&put(unsignedchar);inline ostream&put(signedchar);//写入字符串str的内容到文件

ostream&write(constchar*,int);inline ostream&write(constunsignedchar*,int);inline ostream&write(constsignedchar*,int);//移动输出文件的位置指针

ostream&seekp(streampos); ostream&seekp(streamoff,ios::seek_dir);//取当前输出文件位置指针的值

streampostellp();

…….}第35页,课件共42页,创作于2023年2月3).文件的关闭函数

ofstream类也是从fstreambase类继承的,可以使用fstreambase类的close();来关闭文件。

第36页,课件共42页,创作于2023年2月2.文件的输入文件的输入由类ifstream完成,它由iostream和fstreambase类继承而来,并继承了它的操作符>>函数和文件打开,从文件中读数据、关闭文件的函数。ifstream也提供了构造函数:ifstream();ifstream(constcahr_FAR*,int=ios::in,int=filebuf::openprot);第37页,课件共42页,创作于2023年2月1).文件的打开第一个构造函数用于构造一个不带参数的流,如果需要可以在用它的open函数打开一个文件,下面是open函数的定义:voidopen(constsignedchar_FAR*,int=ios::in,int=filebuf::openprot);它和第二构造函数的使用同文件的输入中的文件打开。

2).文件的数据读出函数可以使用istream类的写数据的函数和操作符把数据写入文件,操作符函数在前面已经介绍,这里实现写数据的函数是:class_CRTIMPistream:virtualpublicios{……public://读取文件数据到字符串内

inlineistream&get(char*,int,char='\n');inlineistream&get(unsignedchar*,int,char='\n');inlineistream&get(signedchar*,int,char='\n');//读取文件数据到字符内

istream&get(char&);inlineistream&get(unsignedchar&);inlineistream&get(signedchar&);istream&get(streambuf&,char='\n');//读取文件一行数据到字符串内

inlineistream&getline(char*,int,char='\n');inlineistream&getline(unsignedchar*,int,char='\n');inlineistream&getline(signedchar*,int,char='\n');inlineistream&ignore(int=1,int=EOF);//读取文件数据到字符串内

istream&read(char*,int);inlineistream&read(unsignedchar*,int);inlineistream&read(signedchar*,int);intgcount()const{returnx_gcount;}intpeek();istream&putback(char);intsync();//移动输入文件指针位置

istream&seekg(streampos);istream&seekg(streamoff,ios::seek_dir);//读取当前输入文件指针位置的值streampostellg();……}

第38页,课件共42页,创作于2023年2月3).文件的关闭函数ifstream类也是从fstreambase类继承的,可以使用fstreambase类的close();来关闭文件。第39页,课件共42页,创作于2023年2月例11.4使用istream和ostream类的文件操作函数把一个文件file.in的内容拷贝到另一个文件file.out。#include<iostream.h>#include<fstream.h>#include<process.h>voidmain(){charch;ifstreamfin(“file.in”);//创建一个输入流,并和输入文件file.in联系ofstreamfout(“file.out”);//创建一输出流,并和输出文件file.out联系if(!fin){cerr<<”Cannotopenfilefile.in”;exit(-1);//如果原文件出错,显示信息并退出}

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论