《C++程序设计教程与实验指导》课件第8章 输入输出流_第1页
《C++程序设计教程与实验指导》课件第8章 输入输出流_第2页
《C++程序设计教程与实验指导》课件第8章 输入输出流_第3页
《C++程序设计教程与实验指导》课件第8章 输入输出流_第4页
《C++程序设计教程与实验指导》课件第8章 输入输出流_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

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

文档简介

第8章输入/输出流8.1输入/输出流概述8.2插入运算符及提取运算符8.3格式化输入输出8.4文件的输入输出8.5输入输出文件流fstream8.1输入/输出流概述8.1.1流的概念“流”是一种抽象的形态,指的是计算机里的数据从一个对象流向另一个对象。这里数据流入和流出的对象通常是指计算机中的屏幕、内存、文件等一些输入输出设备。数据的流动就是由I/O流类来实现的。如预定义流对象cin和cout实现的数据流动过程:C++中的I/O流负责建立程序与设备对象之间的连接,它像一个桥梁,沟通了数据的产生者和消费者,使他们之间产生数据的流动。第8章输入/输出流内存数据流显示器流对象cout键盘数据流内存流对象cin8.1输入/输出流概述8.1.2流类库的结构

第8章输入/输出流ostreamiosistreamiftreamistrstreamistringstreamoftreamostrstreamostringstream

iostreamfstreamstrstreamstingstream第8章输入/输出流类

名说

明包含头文件抽象流基类ios所有输入输出流类的基类ios输入流类istream通用输入流类和其他输入流的基类iostreamifstream输入文件流类fstream输出流类ostream通用输出流类和其他输出流的基类iostreamofstream输出文件流类fstream输入输出流类ostream通用输入/输出流类和其他输入/输出流类的基类iostreamfstream输入/输出文件流类fstreamI/O流类说明表8.1输入/输出流概述8.1.2流类库的结构(续)

流类库中与文件输入输出相关的文件流类结构:第8章输入/输出流iosistreamostreamifstreamofstreamiostreamfstream

返回8.2插入运算符与提取运算符1.插入运算符插入运算符“<<”:通常用于插入数据到一个输出流对象中,流对象再进一步将数据输出到它所关联的设备中。

如:cout<<“HelloWorld!”插入运算符“<<”适用于任何输出流对象,如输出文件流ofstream的对象等。“<<”右侧可以是任何标准数据类型的变量及常量,也可以是字符串变量及常量。如:cout<<i<<‘s’<<3.14<<‘’<<f;

第8章输入/输出流8.2插入运算符与提取运算符2.提取运算符

提取运算符“>>”:通常用于从输入流对象中提取数据。

如:inti;charbuf[100];cin>>i;cin>>buf;提取运算符“>>”适用于任何输入流对象,如输入文件流ifstream的对象等。“>>”右侧可以是任意标准数据类型的变量,也可以是字符串变量。

注意:使用提取运算符“>>”提取数据时,以空白符(如空格、回车、tab)作为数据的分割符,因此提取字符串数据时,不能提取空白字符。第8章输入/输出流

返回8.3格式化输入输出C++中的I/O流可以完成输出/输入的格式化操作,如设置域宽、设置精度及整数进制等。设置输入输出格式的方法:使用流操纵元,只需把流操纵元插入(提取)到输出流(输入流)中即可对输出流(输入流)进行格式化,如setiosflags、setw、setfill、setprecision、hex、oct等,使用流操纵元时需在程序中包含头文件iomanip通过流的成员函数,即由流对象直接调用完成格式化,如setf、unsetf、width、fill、precision等。使用流成员函数的优点是在设置格式同时,可以返回以前的设置,便于恢复原来的设置。第8章输入/输出流8.3格式化输入输出8.3.1输出宽度控制:setw和width使用流操纵元setw和成员函数width可以控制当前域宽(即输入/输出的字符数)。注意:

(1)宽度的设置仅适用于下一个插入或读取的数据。

(2)在输出流中控制域宽,如果输出数据的宽度比设置的域宽小,将以默认右对齐方式输出数据,左边空位会用填充字符来填充(填充字符默认是空格)。

(3)如果输出数据的宽度比设置的宽度大,数据不会被截断,将输出所有位数。第8章输入/输出流例8.1使用setw操纵元控制域宽#include<iostream>#include<iomanip>usingnamespacestd;voidmain(){ cout<<123<<endl; cout<<setw(5)<<4.5<<6.7<<endl;}

程序运行结果为:1234.56.7第8章输入/输出流域宽仅适用于下一个数据;实际数据比设置的域宽小,将右对齐,左补空格例8.2使用width成员函数控制域宽#include<iostream>usingnamespacestd;voidmain(){ char*str[3]={“abc”,“abcde”,“abcdef”}; for(inti=0;i<3;i++) {

cout.width(5);cout<<str[i]<<endl; }}

程序运行结果为:abcabcdeabcdef第8章输入/输出流8.3格式化输入输出8.3.2填充字符控制:setfill和fill

在缺省情况下,如果域宽大于数据宽度时,填充多余空间的字符是空格。如果要改变填充字符,可以使用流操纵元setfill和成员函数fill。

注意:设置了填充字符后,将对程序后面的输出代码产生永久影响,直到下一次再改变填充字符为止。第8章输入/输出流例8.3使用setfill控制填充字符#include<iostream>#include<iomanip>usingnamespacestd;voidmain(){ doublevalues[]={1.23,15.16,653.7,4358.24}; cout<<setfill(‘*’); for(inti=0;i<4;i++) cout<<setw(10)<<values[i]<<endl;}

程序运行结果为:1234.56.7第8章输入/输出流此语句也可以改为:

cout.fill(‘*’);fill()成员函数将返回设置前的填充字符8.3格式化输入输出8.3.3输出精度控制:setprecision和precision

使用流操纵元setprecision以及成员函数precision可以控制浮点数输出的精度。

注意:精度一旦设置,就可以用于以后所有输出的数据,直到下次精度发生改变。使用成员函数precision可以返回设置前的精度。第8章输入/输出流例8.4控制浮点数精度#include<iostream>#include<iomanip>usingnamespacestd;voidmain(){ doublevalue=31.4142743; intPreprecision=cout.precision(4); cout<<value<<endl; cout<<setprecision(Preprecision)<<value<<endl;}

程序运行结果为:31.4131.4143第8章输入/输出流通过precision成员函数设置精度后,将以前精度值返回并保存在变量Preprecision中。注意:系统默认精度为6,恢复原来的精度设置8.3格式化输入输出8.3.3输出精度控制(续)所设置的精度值,在程序没有设置计数法情况下,表示浮点数的有效数字的个数。若程序设置了计数法(ios::fixed或ios::scientific),则表示小数点后数字的个数。

ios::fixed

表示以定点法输出浮点数(不带指数)。

ios::scientific表示以科学计数法输出浮点数。第8章输入/输出流例8.4(续一)#include<iostream>#include<iomanip>usingnamespacestd;voidmain(){ doublevalue=31.4142743;cout<<setiosflags(ios::fixed); intPreprecision=cout.precision(4); cout<<value<<endl; cout<<setprecision(Preprecision)<<value<<endl;}

程序运行结果为:31.414331.414274第8章输入/输出流设置计数法:以定点法输出浮点数例8.4(续二)#include<iostream>#include<iomanip>usingnamespacestd;voidmain(){ doublevalue=31.4142743;cout<<setiosflags(ios::scientific); intPreprecision=cout.precision(4); cout<<value<<endl; cout<<setprecision(Preprecision)<<value<<endl;}

程序运行结果为:3.1414e+0013.141427e+001第8章输入/输出流设置计数法:以科学计数法输出浮点数8.3格式化输入输出8.3.4其他格式状态

上例中的setiosflags也是一个流操纵元,定义在头文件<iomanip>中。通过将setiosflags的参数设置为各种不同流格式状态标志值,可以对相应的输入输出格式进行控制。若需要同时设置多个标志位时,可以使用按位或运算符(|)将不同的标志项结合。第8章输入/输出流第8章输入/输出流流格式状态标志说

明ios::skipwsios::leftios::rightios::internalios::decios::octios::hexios::showbaseios::showpointios::uppercaseios::showposios::scientificios::fixed跳过输入流的空白字符在输出域中左对齐输出,必要时,在右边填充字符在输出域中右对齐输出,必要时,在左边填充字符(默认)在输出域中左对齐数值的符号及进制符号,右对齐数字值以十进制形式格式化指定整数(默认)以八进制形式格式化指定整数以十六进制形式格式化指定整数在数值前输出进制(0表示八进制,0x或0X表示十六进制)输出浮点数时显示小数点和尾部的0输出十六进制数时显示大写字母A~F,科学计数法显示大写E输出正数时前面加正号(+)以科学计数法显示浮点数以定点表示法显示浮点数I/O流格式状态标志例8.5使用setiosflags控制流格式#include<iostream>#include<iomanip>usingnamespacestd;voidmain(){ intx=200; cout<<setiosflags(ios::internal|ios::showpos); cout<<setw(10)<<x<<endl; cout<<setiosflags(ios::hex|ios::uppercase|ios::showbase);cout<<setw(10)<<x<<endl; cout<<oct<<setw(10)<<x<<endl;}

第8章输入/输出流将oct直接插入流中,也可使用:setiosflags(ios::oct)程序运行结果为:+2000XC80310

8.3格式化输入输出8.3.4其他格式状态(续)使用流操纵元setiosflags设置相应的标志位后,对流对象产生的影响是持久的,若想恢复以前的默认设置,可以通过resetiosflags流操纵元关闭相应的标志位。如:cout<<resetiosflags(ios::internal|ios::showbase);可以取消对域中对齐格式的设置,同时取消显示数制标志,恢复系统默认格式。第8章输入/输出流

返回8.4文件的输入输出处理文件输入输出的流类主要有ofstream、ifstream和fstream三个类。均定义在fstream中。向文件输出数据即将数据保存到文件中时,要使用ofstream类;从文件中读取数据即从文件中输入数据时,要使用ifstream类。而使用fstream类可以同时进行输入及输出操作。

文件输入输出的一般步骤为:

创建流对象并打开文件→读写文件→关闭文件第8章输入/输出流8.4文件的输入输出8.4.1打开文件1.

使用默认构造函数,然后调用open函数用法如下:文件I/O流类名流对象名;//声明一个流对象流对象名.open(文件名,打开方式);//调用open函数打开文件如:ofstreammy_file; my_file.open(“boot.ini”,ios::out);参数“文件名”:用于指定要打开文件的文件名

若为不带路径的文件名表示与当前应用程序在同一文件夹若带路径的文件名,注意‘\’应用‘\\’表示第8章输入/输出流8.4文件的输入输出8.4.1打开文件(续一)参数“打开方式”:用于指定文件的打开方式第8章输入/输出流打开方式说

明ios::inios::outios::appios::ateios::nocreateios::noreplaceios::truncios::binary打开一个输入文件,是ifstream对象的默认方式打开一个输出文件,是ofstream对象的默认方式。若打开一个已有文件,则删除原有内容,若打开的文件不存在,则将创建该文件。打开一个输出文件,用于在文件末尾添加数据,不删除文件原有内容打开一个现有文件(用于输入或输出),并定位到文件结尾仅打开一个存在的文件(不存在则失败)仅打开一个不存在的文件(存在则失败)打开一个输出文件,如果它存在则删除文件原有内容以二进制模式打开一个文件(默认是文本模式)8.4文件的输入输出8.4.1打开文件(续二)2.

在构造函数中直接指定文件名及打开方式用法如下:文件I/O流类名流对象名(文件名,打开方式);如:ifstreaminfile(“D:\\hello.dat”,ios::binary

);第8章输入/输出流如果使用以上两种方法打开文件不成功(如文件路径不正确),文件流对象将为0,因此习惯上可用如下方式判断打开操作是否失败:if(!my_file){……}//如果打开文件的操作不成功8.4文件的输入输出8.4.2写入文件如果写入的是标准数据类型的数据或字符串,可以直接通过插入运算符(<<),将数据插入到输出文件流对象中。如:ofstream

my_file(“D:\\data.txt”,ios::out);

my_file

<<“Hello!”<<‘’<<234<<endl;

使用插入运算符在写入数据时仅局限于标准数据类型及字符串,对于自定义类型的数据并不能直接插入。第8章输入/输出流空格,是为了在文件中将数据分隔开,以便在读出时能正确区分数据。8.4文件的输入输出8.4.2写入文件(续一)1.

put函数:使用put函数可以将一个单个字符写入流对象,进而写入流对象所关联的文件中。put函数每次只能写一个字符。用法如下:

my_file.put(‘A’);

char

ch=‘A’;my_file.put(ch);

注意:使用put函数输出数据不受格式影响,即设置的域宽和填充字符对于put函数不起作用。第8章输入/输出流8.4文件的输入输出8.4.2写入文件(续二)2.

write函数:把内存中的一块内容写入输出流对象中。主要用于输出数组及自定义类型变量等具有连续内存的数据。

write函数的第一个形参:

用于指定输出数据的内存起始地址,该地址为字符型(char*),因此传递的实参应为字符型的指针。

write函数的第二个形参:

用于指定所写入的字节数,即从该起始地址开始写入多少字节的数据,第二个形参类型为整型。第8章输入/输出流例8.6使用write函数输出CRect类的对象#include<fstream>usingnamespacestd;voidmain(){ CRectr; r.SetColor(“Red”); r.Move(10,20); r.SetSize(100,200); ofstreamoutfile(“D:\\a.txt”,ios::out); outfile.write((char*)&r,sizeof(r)); outfile.close();//调用close函数关闭文件}

第8章输入/输出流定义输出文件流对象并打开文件进行输出将r地址强制类型转换(char*)为字符型指针例8.7使用write函数输出整型数组#include<fstream>usingnamespacestd;voidmain(){ intarray[]={35,42,57,88,69,75}; ofstreamoutfile2(“D:\\a.txt”,ios::app); outfile2.write((char*)array,sizeof(array)); outfile2.close();}

第8章输入/输出流在打开的文件尾添加数据将数组首地址强制类型转换若将主函数的array数组改为:chararray[]=“helloworld!”;则write语句将变为:outfile2.write(array,sizeof(array));无须强制类型转换8.4文件的输入输出8.4.3读取文件如果读取的是标准数据类型的数据或字符串,可以直接通过提取运算符(>>),将数据从输入文件流对象读取到程序的变量中。使用提取运算符提取数据时,将以空白字符(如空格、Tab、回车)作为数据之间的分隔符,因此这些空白字符不能被作为数据提取出来。如:char

s[10];

int

i;ifstream

in_file(“D:\\data.txt”,ios::in);

in_file>>s>>i;第8章输入/输出流若文件中数据为:Hello!234则s和i的数据分别为:“Hello!”、2348.4文件的输入输出8.4.3读取文件(续一)1.

get函数:使用get函数可以从流对象中提取一个单个字符,get函数弥补了提取运算符不能提取空白字符的缺点,它能把任意字符包括空白符提取出来。get函数提取一个字符时,有带形参和不带形参两种形式:

如:char

ch;

ch=cin.get();

或:

cin.get(ch);

若以上语句中调用get函数的是一个输入文件流对象,则将从该流对象所关联的文件中提取出单个字符。第8章输入/输出流8.4文件的输入输出8.4.3读取文件(续二)2.

getline函数:用于从流对象中提取多个字符,通常用于提取一行字符。get函数有三个形参。

get函数的第一个形参:

为字符型指针(char*),用于存放读出的多个字符,通常传递的实参为字符数组。

get函数的第二个形参:

为整型,用于指定本次读取的最大字符个数。

get函数的第三个形参:

为字符型,默认值为回车符(‘\n’),用于指定分隔字符,作为一次读取结束的标志。第8章输入/输出流例8.8读取文件E:\boot.txt中的内容,并输出到屏幕上#include<fstream>#include<iostream>usingnamespacestd;voidmain(){ chararray[100]; ifstreamifs(“E:\\boot.txt”,ios::nocreate); if(!ifs) return;//如果文件不存在,打开不成功,则结束程序 while(!ifs.eof())//eof函数用于判断是否到文件尾,到文件尾返回True { ifs.getline(array,100);//100表示每次读取字符的个数最多为99个 cout<<array<<endl; } ifs.close();}第8章输入/输出流使用getline函数按行读取文件中的数据,每次读取一行时,遇回车符或达到最大字符个数,则结束,并将读出数据保存于数组array中。

8.4文件的输入输出8.4.3读取文件(续三)3.

read函数:从流对象中提取整块数据到变量中,主要用于提取数据到数组及自定义类型变量中。

read函数的第一个形参:

用于保存读出的数据,类型为字符型指针(char*),与write函数中用法一致。

read函数的第二个形参:

用于指定读出多少个字节,类型为整型。与write函数中用法一致。第8章输入/输出流例8.9读取例10.6中输出到文件“D:\a.txt”中的内容,并将矩形参数显示到屏幕上#include<fstream>#include<iostream>usingnamespacestd;voidmain(){ CRectr2; ifstreamifile(“D:\\a.txt”); ifile.read((char*)&r2,sizeof(r2));//将读出的数据保存到矩形对象r2中 ifile.close(); r2.Draw();}第8章输入/输出流程序运行结果为:矩形左上角坐标为(20,10)矩形长和宽分别为100,200矩形的颜色是red8.4文件的输入输出8.4.4文件读写位置指针

位置指针:用于保存在文件中进行读或写的位置。通过对位置指针的操作,适当地调整读或写的位置,可以实现对磁盘文件的随机访问。与ofstream对应的是写位置指针,指定下一次写数据的位置。相关的操作函数为:

seekp函数:用于移动指针到指定位置。

tellp函数:用于返回指针当前的位置。

与ifstream对应的是读位置指针,指定下一次读数据的位置。相关的操作函数为:

seekg函数:用于移动指针到指定位置。

tellg函数:用于返回指针当前的位置。第8章输入/输出流8.4文件的输入输出8.4.4文件读写位置指针(续)

seekg函数的使用形式(seekp类似):

seekg(n):用于移动指针到文件第n个字节后。

seekg(n,ios::beg):从文件起始位置向后移动n个字节。seekg(n,ios::end):从文件结尾位置向前移动n个字节。

seekg(n,ios::cur):从当前位置向前或向后移动n个字节。

其中:n=0,在指定位置;n>0,在指定位置向后移动;n<0,在指定位置向前移动。

tellg函数的使用形式(tellp类似):

streamposn=流对象.tellg()

streampos可看作整型数据,返回值保存指针当前的位置。第8章输入/输出流例8.10

已知文件data.txt中存有10个CRect对象的数据,现要求读取最后一个对象,把它的左上角坐标修改为(100,100),其他不变,修改后写回到文件中去。#include<fstream>

usingnamespacestd; voidmain() { CRectrt; ifstreamifs(“data.txt”); ifs.seekg(0,ios::end);//将指针移动到文件尾

streamposlof=ifs.tellg();//求得文件长度lof ifs.seekg(-lof/10,ios::end);//将指针移动到最后一条记录起始位置

ifs.read((char*)&rt,sizeof(CRect)); ifs.close(); rt.Move(100,100); ofstreamofs(“data.txt”,ios::ate);//以ios::ate方式打开文件防止删除原来内容

ofs.seekp(-lof/10,ios::end);//将指针移动到最后一条记录起始位置

ofs.write((char*)&rt,sizeof(CRect)); ofs.close(); }

第8章输入/输出流8.4文件的输入输出8.4.5错误处理函数

eof()——如果输入流结束,到文件尾,则返回True;

bad()——如果出现一个严重的、不可恢复的错误,如由于非法操作导致数据丢失、对象状态不可用等,则返回True,通常这种错误不可修复,此时不要对流再进行I/O操作;

fail()——如果某种操作失败,如打开操作不成功,或不能读出数据,或读出数据的类型不符等等,则返回True;

good()——如果以上三种错误均未发生,表示流对象状态正常,则返回True。以上函数可由流对象直接调用,如:if(!inf.eof())//如果没有到文件末尾,if条件满足第8章输入/输出流8.4文件的输入输出8.4.6关闭文件文件使用完毕后必须将其关闭才能断开流和对象之间的联系。文件关闭后,还可以再次与流对象关联,打开文件进行输入或输出操作。使用流对象的close函数可以完成关闭文件的操作,close函数无形参,

温馨提示

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

最新文档

评论

0/150

提交评论