29
11.1 11.1 输输 输输 / / 输输输 输输输 输输 输输 11.2 11.2 输输输输 输输输输 / / 输输输 输输输 11.3 11.3 输输 输输 / / 输输输输输输 输输输输输输 11.4 11.4 输输输输 输输输输 / / 输输 输输 11.5 11.5 输输输输输输输输输输 输输输输输输输输输输 / / 输输 输输 11.6 11.6 输输输输 输输输输 11 11 输输 输输 / / 输输输 输输输

第 11 章 输入/输出流

  • Upload
    denali

  • View
    200

  • Download
    0

Embed Size (px)

DESCRIPTION

第 11 章 输入/输出流. 11.1 输入/输出流 概述 11.2 标准输入 / 输出流 11.3 输入 / 输出格式控制 11.4 文件输入 / 输出 11.5 用户自定义类型的输入 / 输出 11.6 综合实例. 【 11.1 输入 / 输出流概述 】. 输入输出 (I/O) 是所有高级语言都必须具备的基本功能。 C++ 语言中也没有输入 / 输出语句。 C++ 语言是通过 I/O 流来实现输入 / 输出的 。 I/O 流不是 C++ 语言的一部分,而是标准 C++ 库的一部分,是 C++ 类的一个集合,本章主 - PowerPoint PPT Presentation

Citation preview

Page 1: 第   11  章 输入/输出流

11.1 11.1 输入输入 // 输出流输出流概述概述

11.2 11.2 标准输入标准输入 // 输出流输出流

11.3 11.3 输入输入 // 输出格式控制输出格式控制

11.4 11.4 文件输入文件输入 // 输出输出

11.5 11.5 用户自定义类型的输入用户自定义类型的输入 // 输出输出

11.6 11.6 综合实例综合实例

第 第 11 11 章章 输入输入 // 输出流输出流

Page 2: 第   11  章 输入/输出流

输入输出输入输出 (I/O)(I/O) 是所有高级语言都必须具备的基本功能。是所有高级语言都必须具备的基本功能。 C++C++ 语言中也没语言中也没有输入有输入 // 输出语句。输出语句。 C++C++ 语言是通过语言是通过 I/OI/O 流来实现输入流来实现输入 // 输出的输出的。。 I/OI/O 流不流不是是 C++C++ 语言的一部分,而是标准语言的一部分,而是标准 C++C++ 库的一部分,是库的一部分,是 C++C++ 类的一个集合,类的一个集合,本章主本章主要介绍要介绍 I/OI/O 流的使用,包括格式化输入输出、用户自定义类型的输入输出。流的使用,包括格式化输入输出、用户自定义类型的输入输出。

流的概念流的概念始终和设备无关性密切相关,所谓始终和设备无关性密切相关,所谓设备无关性设备无关性是指编程者不必关是指编程者不必关心所访问的特定设备的各种细节变化,他的程序可以根本不做改动或者只心所访问的特定设备的各种细节变化,他的程序可以根本不做改动或者只做少量改动就可以访问不同设备。做少量改动就可以访问不同设备。设备无关性是程序可移植和可重用性的设备无关性是程序可移植和可重用性的重要标志。重要标志。

通过流的概念,可以将要输入或者输出的数据看作一个字节流,通过流的概念,可以将要输入或者输出的数据看作一个字节流,而不必考虑具体设备的特定细节。而不必考虑具体设备的特定细节。

注注

【【 11.111.1 输入输入 // 输出流概输出流概述述】】

Page 3: 第   11  章 输入/输出流

预定义的流对象预定义的流对象

标准输入流标准输入流 cincin

标准输出流标准输出流 coutcout

与标准输入设备键盘相关联与标准输入设备键盘相关联

与标准输出流显示器相关联与标准输出流显示器相关联非缓冲型的标准出错流非缓冲型的标准出错流 cerrcerr

缓冲型的标准出错流缓冲型的标准出错流 clogclog

将将流看成是一个对象流看成是一个对象,这个对象要与某种设备相联系,如与输入设备相联,这个对象要与某种设备相联系,如与输入设备相联系的流是系的流是输入流输入流,与输出设备相联系的流是,与输出设备相联系的流是输出流输出流,与输入输出设备相联,与输入输出设备相联系的流则是系的流则是输入输出流输入输出流。。

C++C++ 语言完全支持语言完全支持 CC 语言的语言的 I/OI/O 系统,此外还定义了一套面向对象的系统,此外还定义了一套面向对象的 I/OI/O系统。通过面向对象的系统。通过面向对象的 I/OI/O 系统,系统, C++C++ 语言可以支持用户自定义的各种语言可以支持用户自定义的各种类的类的对象的输入输出。支持面向对象的特征。对象的输入输出。支持面向对象的特征。

【【 11.111.1 输入输入 // 输出流概输出流概述述】】

Page 4: 第   11  章 输入/输出流

iosios

istreamistream ostreamostream

istrstreamistrstream

ifstreamifstream

istream_withassignistream_withassign ostream_withassignostream_withassign

ofstreamofstream

ostrstreamostrstream

iostreamiostream

stdiostreamstdiostreamfstreamfstream strstreamstrstream

streambufstreambuf

stdiobufstdiobuffilebuffilebuf strstreambufstrstreambuf

图图 各类之间的关系各类之间的关系

Page 5: 第   11  章 输入/输出流

【【 11.2 11.2 标准输入标准输入 // 输出流输出流】】 标准输出流标准输出流 coutcout ,是一个系统预先定义好的,是一个系统预先定义好的 ostreamostream 类的派生类对象,类的派生类对象,它与标准输出设备(显示器)相联系,可以实现数据的显示。正如前面看它与标准输出设备(显示器)相联系,可以实现数据的显示。正如前面看到的,到的, coutcout 可以通过“可以通过“ <<”<<” 共同完成对数据的输出,其中“共同完成对数据的输出,其中“ <<”<<” 被称为被称为流插入运算符,或者简称插入符。流插入运算符,或者简称插入符。

为什么为什么 coutcout 对象可以把不同类型的数据按类似的方法输出呢?对象可以把不同类型的数据按类似的方法输出呢?原因就在于原因就在于 ostreamostream 类对“类对“ <<”<<” 插入符进行了运算符重载,用来处理各种插入符进行了运算符重载,用来处理各种基本数据类型的输出。基本数据类型的输出。

注注

例 例 11-311-3 指针值的显示指针值的显示

//EXAMPLE11_3.CPP//EXAMPLE11_3.CPP//// 源程序开始源程序开始#include <iostream.h>#include <iostream.h>int main()int main(){{

int value=100;int value=100;int * iptr=&value;int * iptr=&value;

Page 6: 第   11  章 输入/输出流

//// 显示显示 valuevalue 值值cout<<”value =”<<value<<endl;cout<<”value =”<<value<<endl;//// 显示显示 valuevalue 存放地址存放地址 (( 指针指针 ))cout<<”&value =”<<&value<<endl;cout<<”&value =”<<&value<<endl;//// 显示显示 iptriptr 值(保存了值(保存了 valuevalue 的地址)的地址)cout<<”iptr =”<<iptr<<endl;cout<<”iptr =”<<iptr<<endl;//// 显示显示 iptriptr 自身地址自身地址cout<<”&iptr =”<<&iptr<<endl;cout<<”&iptr =”<<&iptr<<endl;return 0;return 0;

}}

程序运行结果:

value =100value =100&value =0012FF7C&value =0012FF7Ciptr =0012FF7Ciptr =0012FF7C&iptr =0012FF78&iptr =0012FF78

Page 7: 第   11  章 输入/输出流

标准输入流标准输入流 cincin ,与标准输出流对象,与标准输出流对象 coutcout 类似,类似, cincin 也是一个系统预先也是一个系统预先定义好的定义好的 istreamistream 类的派生类对象,它与标准输入设备(通常是键盘)相类的派生类对象,它与标准输入设备(通常是键盘)相联系,可以实现数据的输入。联系,可以实现数据的输入。 cincin 可以通过“可以通过“ >>”>>” 完成数据的输入,其中完成数据的输入,其中““ >>”>>” 被称为流提取运算符,或者简称提取符。被称为流提取运算符,或者简称提取符。

例 例 11-511-5 使用提取运算符进行数据的连续输入使用提取运算符进行数据的连续输入

//EXAMPLE11_5.CPP//EXAMPLE11_5.CPP//// 源程序开始源程序开始#include <iostream.h>#include <iostream.h>int main()int main(){{

int i;int i;double f;double f;char str[30];char str[30];cout<<"cout<<" 请输入请输入 ii 、、 ff 和和 str : ";str : ";cin>>i>>f>>str;cin>>i>>f>>str;cout<<"cout<<" 你输入的数据分别是:你输入的数据分别是: "<<i<<" , "<<f<<" , "<<str<<endl;"<<i<<" , "<<f<<" , "<<str<<endl;return 0;return 0;

}}程序运行结果:程序运行结果: 请输入请输入 ii 、、 ff 和和 str : 1 2.22 TestStreamstr : 1 2.22 TestStream

你输入的数据分别是:你输入的数据分别是: 1 , 2.22 , TestStream1 , 2.22 , TestStream

Page 8: 第   11  章 输入/输出流

一般在进行输入输出格式控制时需要使用一般在进行输入输出格式控制时需要使用 iosios 类中的相关成员函数类中的相关成员函数或者是或者是操纵子函数操纵子函数。。

在在 iosios 类中控制输入输出的成员函数有: 类中控制输入输出的成员函数有: int ios::width(); int ios::width(); //// 返回当前的宽度设置返回当前的宽度设置int ios::width(int w); int ios::width(int w); //// 设置宽度并返回前一次的设置设置宽度并返回前一次的设置int ios::precision(int p); int ios::precision(int p); //// 设置精度并返回前一次设置值设置精度并返回前一次设置值char ios::fill(); char ios::fill(); //// 返回当前空位填充的字符返回当前空位填充的字符char ios::fill(char ch); char ios::fill(char ch); //// 设置空位填充字符设置空位填充字符long ios::setf(long flags); long ios::setf(long flags); //// 设置状态标志设置状态标志long ios::unsetf(long flags); long ios::unsetf(long flags); //// 清除状态标志清除状态标志long ios::flags(); long ios::flags(); //// 测试状态标志测试状态标志long ios::flags(long flags); long ios::flags(long flags); //// 设置状态标志并返回前一次的状态标志设置状态标志并返回前一次的状态标志

状态标志是各种状态值之间通过或运算组合而成的,在状态标志是各种状态值之间通过或运算组合而成的,在 iosios 类中类中是一个公共的枚举类型。是一个公共的枚举类型。

注注

【【 11.3 11.3 输入输入 // 输出格式控制输出格式控制】】

Page 9: 第   11  章 输入/输出流

标 志标 志 标 志 含 义标 志 含 义跳过输入中的空白跳过输入中的空白输出数据左对齐输出数据左对齐输出数据右对齐输出数据右对齐在指定符号位或基指示符之后加入填充字符在指定符号位或基指示符之后加入填充字符基为十进制基为十进制基为八进制基为八进制基为十六进制基为十六进制生成一个前缀标明生成的整数输出的基生成一个前缀标明生成的整数输出的基

skipwsskipws

leftleftrightright

octoct

hexhex

showbaseshowbase

showpointshowpoint 显示浮点数的小数点和后面的显示浮点数的小数点和后面的 00

internalinternal

decdec

输出时以大写字母代替相应的小写字母输出时以大写字母代替相应的小写字母正数前面的正号被显示正数前面的正号被显示按科学记数法表示浮点数按科学记数法表示浮点数以定点格式显示浮点数以定点格式显示浮点数

showposshowpos

scientificscientific

fixedfixed

unitbufunitbuf 插入操作后立即刷新缓冲区插入操作后立即刷新缓冲区

uppercaseuppercase

boolalphaboolalpha 在字母格式中插入和提取布尔类型在字母格式中插入和提取布尔类型stdiostdio 插入操作后清空每个流插入操作后清空每个流

表 表 isoiso 类中各个标志代表的含义类中各个标志代表的含义

Page 10: 第   11  章 输入/输出流

使用使用 iosios 类成员函数控制输出格式类成员函数控制输出格式

//EXAMPLE11_6.CPP//EXAMPLE11_6.CPP//// 源程序开始源程序开始#include <iostream.h>#include <iostream.h>int main()int main(){{

const int n=3;const int n=3; int test[]={1024,2048,3072};int test[]={1024,2048,3072};

for(int i=0;i<n;i++)for(int i=0;i<n;i++){{

cout.setf(ios::oct|ios::showbase|ios::showpos);cout.setf(ios::oct|ios::showbase|ios::showpos); //// 设置标志八进制,显示基及正号设置标志八进制,显示基及正号

cout<<test[i]<<" ";cout<<test[i]<<" ";cout.unsetf(ios::oct);//cout.unsetf(ios::oct);// 解除八进制设置解除八进制设置cout.setf(ios::hex|ios::showbase|ios::showpos);cout.setf(ios::hex|ios::showbase|ios::showpos);

//// 设置标志十六进制,显示基及正号设置标志十六进制,显示基及正号cout<<test[i]<<" ";cout<<test[i]<<" ";cout.unsetf(ios::hex); cout.unsetf(ios::hex); ////解除十六进制设置解除十六进制设置cout<<test[i]<<endl;cout<<test[i]<<endl;

}} cout<<endl;cout<<endl; cout.fill('#'); cout.fill('#'); //// 设置填充符号为设置填充符号为 ##

例 例 11-611-6

(( 续续 ))

Page 11: 第   11  章 输入/输出流

for(i=0;i<n;i++)for(i=0;i<n;i++){{

cout.width(8); cout.width(8); //// 设置输出域宽度为设置输出域宽度为 88cout<<test[i]<<" ";cout<<test[i]<<" ";

}}cout<<endl;cout<<endl;

cout.fill(‘*’); cout.fill(‘*’); //// 将填充字符设置为将填充字符设置为 **for(i=0;i<n;i++)for(i=0;i<n;i++){{

cout.width(8);cout.width(8);cout<<test[i]<<" ";cout<<test[i]<<" ";

}}cout<<endl;cout<<endl;return 0;return 0;

}}

程序输出: 02000 0x400 +102402000 0x400 +1024 04000 0x800 +204804000 0x800 +2048 06000 0xc00 +307206000 0xc00 +3072 ###+1024 ###+2048 ###+3072###+1024 ###+2048 ###+3072 ***+1024 ***+2048 ***+3072***+1024 ***+2048 ***+3072

Page 12: 第   11  章 输入/输出流

操 纵 子操 纵 子 说 明说 明以十进制格式以十进制格式以十六进制格式以十六进制格式以八进制为格式以八进制为格式输入跳过开始的空格输入跳过开始的空格换行并刷新输出流换行并刷新输出流插入空字符结束字符串插入空字符结束字符串刷新输出流刷新输出流转换基数设置转换基数设置

decdec

hexhexoctoct

endsends

flushflush

setbasesetbase

setiosflags(long f)setiosflags(long f) 设置格式标志设置格式标志

wsws

endlendl

解除格式标志设置解除格式标志设置填充字符填充字符设置数据精度设置数据精度设置输出宽度设置输出宽度

setfill(int c)setfill(int c)

setprecision(int p)setprecision(int p)

setw(int w)setw(int w)

resetiosflags(long f)resetiosflags(long f)

表 表 C++C++ 中预定义的操纵子表中预定义的操纵子表

设置设置 I/OI/O 格式还有另外一种途径,就是使用格式操纵子。格式操纵子格式还有另外一种途径,就是使用格式操纵子。格式操纵子可以直接嵌入到输入输出语句中。格式操纵子分为带参数和不带参数两种。可以直接嵌入到输入输出语句中。格式操纵子分为带参数和不带参数两种。

注注

Page 13: 第   11  章 输入/输出流

使用格式操纵子控制输出格式使用格式操纵子控制输出格式//EXAMPLE11_8.CPP//EXAMPLE11_8.CPP//// 源程序开始源程序开始 #include <iostream.h>#include <iostream.h>#include <iostream.h>#include <iostream.h>#include <iomanip.h>#include <iomanip.h>#include <math.h>#include <math.h>int main()int main(){{ const double pi=3.141592653589793;const double pi=3.141592653589793;

int i;int i;cout<<setiosflags(ios::right); cout<<setiosflags(ios::right); //// 设置标志为右对齐输出设置标志为右对齐输出cout<<setiosflags(ios::scientific|ios::uppercase);cout<<setiosflags(ios::scientific|ios::uppercase);

//// 设置标志为科学记数法,显示大写设置标志为科学记数法,显示大写 EEcout<<setprecision(8); cout<<setprecision(8); //// 设置输出精度为设置输出精度为 44for(i=0;i<360;i+=60)for(i=0;i<360;i+=60){{

cout<<"sin(";cout<<"sin(";cout<<setw(3)<<i<<")=";cout<<setw(3)<<i<<")=";cout<<setw(17)<<sin(i/180.0*pi)<<" ; ";cout<<setw(17)<<sin(i/180.0*pi)<<" ; ";cout<<"cos(";cout<<"cos(";cout<<setw(3)<<i<<")=";cout<<setw(3)<<i<<")=";cout<<setw(17)<<cos(i/180.0*pi)<<endl;cout<<setw(17)<<cos(i/180.0*pi)<<endl;

}}

例 例 11-811-8

(( 续续 ))

Page 14: 第   11  章 输入/输出流

return 0;return 0;}}

程序输出:

sin( 0)= 0.00000000E+000 ; cos( 0)= 1.00000000E+000sin( 0)= 0.00000000E+000 ; cos( 0)= 1.00000000E+000sin( 60)= 8.66025404E-001 ; cos( 60)= 5.00000000E-001sin( 60)= 8.66025404E-001 ; cos( 60)= 5.00000000E-001sin(120)= 8.66025404E-001 ; cos(120)= -5.00000000E-001sin(120)= 8.66025404E-001 ; cos(120)= -5.00000000E-001sin(180)= 1.22460635E-016 ; cos(180)= -1.00000000E+000sin(180)= 1.22460635E-016 ; cos(180)= -1.00000000E+000sin(240)= -8.66025404E-001 ; cos(240)= -5.00000000E-001sin(240)= -8.66025404E-001 ; cos(240)= -5.00000000E-001sin(300)= -8.66025404E-001 ; cos(300)= 5.00000000E-001sin(300)= -8.66025404E-001 ; cos(300)= 5.00000000E-001

由于误差, 180 度的正弦值不为 0 。 注注

Page 15: 第   11  章 输入/输出流

文件输入输出也分为文件输入输出也分为二进制二进制和和文本方式文本方式,也要,也要首先创建流,将该流与某个首先创建流,将该流与某个具体文件相关联具体文件相关联 (( 打开文件打开文件 )) ,然后进行读写操作,最后关闭该文件。,然后进行读写操作,最后关闭该文件。

使用使用 33 种流类进行文件的输入输出种流类进行文件的输入输出:: ifstreamifstream 、、 ofstreamofstream 、、 fstreamfstream 它们它们的基类分别是的基类分别是 istreamistream 、、 ostreamostream 、、 iostreamiostream 。。

可以使用成员函数可以使用成员函数 open()open() 和和 close()close() 进行文件的打开和关闭操作进行文件的打开和关闭操作

open()open() 函数的原型为:函数的原型为:void open(const char *filename, int filemode, int access=filebuf::openprot);void open(const char *filename, int filemode, int access=filebuf::openprot);

文件的打开方式必须取下表所示的一个或者其组合文件的打开方式必须取下表所示的一个或者其组合注注

filenamefilename 包含路径的文件名包含路径的文件名

filemodefilemode 为文件的打开方式为文件的打开方式

accessaccess 为文件的存取属性为文件的存取属性

【【 11.4 11.4 文件输入文件输入 // 输输出出】】

Page 16: 第   11  章 输入/输出流

打 开 方 式打 开 方 式 含 义含 义使输出追加到文件尾使输出追加到文件尾查找文件尾查找文件尾从文件中读从文件中读打开不存在的文件时失败打开不存在的文件时失败文件存在时打开失败文件存在时打开失败写写同名文件被删除同名文件被删除文件以二进制方式打开文件以二进制方式打开

Ios::appIos::app

Ios::ateIos::ateIos::inIos::in

Ios::outIos::out

Ios::truncIos::trunc

Ios::binaryIos::binary

setiosflags(long f)setiosflags(long f) 设置格式标志设置格式标志

Ios::nocreateIos::nocreate

Ios::noreplaceIos::noreplace

文件的访问方式文件的访问方式

00———— 普通文件普通文件11———— 只读文件只读文件

22———— 隐含文件隐含文件

44———— 系统文件系统文件

88———— 备份文件备份文件

表表 文体的打开方式文体的打开方式

Page 17: 第   11  章 输入/输出流

istream& get(unsigned char ch);istream& get(unsigned char ch);

istream& getline(char * str, streamsize n);istream& getline(char * str, streamsize n);

ostream& put(char ch);ostream& put(char ch);

istream& read(unsigned char * buffer, int num);istream& read(unsigned char * buffer, int num);

ostream& write(const unsigned char * buffer, int num);ostream& write(const unsigned char * buffer, int num);

由于缓冲区首地址的数据类型为由于缓冲区首地址的数据类型为 unsigned char *, unsigned char *, 所以输入输出所以输入输出其他类型数据时其他类型数据时必须进行强制类型转换必须进行强制类型转换。 。

注注

get()get() 函数函数可以从与流对象相关联的文可以从与流对象相关联的文件中读取数据,每次读一个字节。件中读取数据,每次读一个字节。

getline()getline() 则容许从输入流中读取多个则容许从输入流中读取多个字符,并容许指定输入终止字符。字符,并容许指定输入终止字符。

read()read() 函数函数可以从流中读取可以从流中读取 numnum 个字个字节,并放入节,并放入 bufferbuffer 所指的缓冲区中。所指的缓冲区中。

write()write() 函数函数把把 bufferbuffer 所指向的缓冲区所指向的缓冲区中中 numnum 个字节写到相应的流中。个字节写到相应的流中。

put()put() 函数可以向与流相关联的文件函数可以向与流相关联的文件中写入数据,每次写一个字符。 中写入数据,每次写一个字符。

输入输出流的主要成员函数除输入输出流的主要成员函数除 openopen 和和 closeclose 外还有:外还有:

Page 18: 第   11  章 输入/输出流

istream& seekg(streamoff offset, seekdir origin);istream& seekg(streamoff offset, seekdir origin);

ostream& seekp(streamoff offset, seekdir origin);ostream& seekp(streamoff offset, seekdir origin);

streampos tellg();streampos tellg();

streampos tellp();streampos tellp();

originorigin 是每举变量,可以有下面三个值: 是每举变量,可以有下面三个值:

ios::beg ios::beg ////从文件头开始从文件头开始ios::cur ios::cur ////从文件当前位置开始从文件当前位置开始ios::end ios::end ////从文件尾开始从文件尾开始

seekg()seekg() 函数函数用于输入,将相应的文件读用于输入,将相应的文件读指针从指针从 originorigin 的位置偏置的位置偏置 offsetoffset 个字节。个字节。

seekp()seekp() 函数函数用于输出,将相应的文件写指用于输出,将相应的文件写指针从针从 originorigin 的位置偏置的位置偏置 offsetoffset 个字节。个字节。

函数函数 tellg()tellg() 和函数和函数 tellp()tellp() 则用于输入输出则用于输入输出文件时确定文件指针的当前位置。文件时确定文件指针的当前位置。

Page 19: 第   11  章 输入/输出流

文件文件 I/OI/O

//EXAMPLE11_9.CPP//EXAMPLE11_9.CPP//// 源程序开始源程序开始#include <iostream.h>#include <iostream.h>#include <fstream.h>#include <fstream.h>#include <string.h>#include <string.h>int main()int main(){{

int testi[]={1111,2222, 3333,4444}; //int testi[]={1111,2222, 3333,4444}; // 要写入文件的数据要写入文件的数据char *tests[]={"This", "is", "a", "file"};char *tests[]={"This", "is", "a", "file"};

  char fwi[30] ,fri[30], fws[30],frs[30]; //char fwi[30] ,fri[30], fws[30],frs[30]; // 文件名文件名int tmpi; int tmpi; char tmps[80];char tmps[80];

  ofstream ofi,ofs;//ofstream ofi,ofs;// 输出流对象输出流对象ifstream ifi, ifs;//ifstream ifi, ifs;// 输入流对象输入流对象

  

例 例 11-911-9

Page 20: 第   11  章 输入/输出流

cout<<"Please input the file name which you want to output integer:"<<endl;cout<<"Please input the file name which you want to output integer:"<<endl;cin>>fwi; //cin>>fwi; // 获得整数输出文件名获得整数输出文件名

ofi.open(fwi);//ofi.open(fwi);// 打开输出文件打开输出文件for(int i=0;i<4;i++)for(int i=0;i<4;i++){{

ofi<<testi[i]<<" ";//ofi<<testi[i]<<" ";// 向输出文件中写数据向输出文件中写数据}}ofi<<endl;ofi<<endl;

cout<<"Please input the file name whick you want to output string:"<<endl;cout<<"Please input the file name whick you want to output string:"<<endl;cin>>fws;//cin>>fws;// 获得字符输出文件名获得字符输出文件名

ofs.open(fws);//ofs.open(fws);// 打开输出文件打开输出文件for(i=0;i<4;i++)for(i=0;i<4;i++){{

ofs<<tests[i]<<" ";//ofs<<tests[i]<<" ";// 向输出文件写数据向输出文件写数据}}ofs<<endl;ofs<<endl;  ofi.close();//ofi.close();// 关闭输出文件关闭输出文件ofs.close();//ofs.close();// 关闭输出文件 关闭输出文件 (续)(续)

Page 21: 第   11  章 输入/输出流

strcpy(fri,fwi);//strcpy(fri,fwi);// 获得输入文件名,与前面输出文件同名获得输入文件名,与前面输出文件同名strcpy(frs,fws);strcpy(frs,fws);

ifi.open(fri);//ifi.open(fri);// 打开输入文件打开输入文件ifs.open(frs);//ifs.open(frs);// 打开输入文件打开输入文件for(i=0;i<4;i++)for(i=0;i<4;i++){{

ifi>>tmpi;//ifi>>tmpi;// 从输入文件中读数据从输入文件中读数据cout<<tmpi<<" ";cout<<tmpi<<" ";

}}cout<<endl;cout<<endl;

for(i=0;i<4;i++)for(i=0;i<4;i++){{

ifs>>tmps;//ifs>>tmps;// 从输入文件中读数据从输入文件中读数据cout<<tmps<<" ";cout<<tmps<<" ";

}}cout<<endl;cout<<endl;return 0;return 0;

}}

说明:按提示输入要写入的文件名说明:按提示输入要写入的文件名 (( 包含路径包含路径 )) 后,后,将建立以该文件名命名的新文件,并分别将将建立以该文件名命名的新文件,并分别将 1111 2221111 2222 3333 44442 3333 4444 和字符串″和字符串″ This is a file″This is a file″ 写到这两个文件写到这两个文件中,并将写入的内容读出来显示在输出窗口。中,并将写入的内容读出来显示在输出窗口。

(续)(续)

Page 22: 第   11  章 输入/输出流

#include <fstream.h>#include <fstream.h>

int main()int main(){{ double dbl;double dbl; fstream myio; fstream myio; ////声明输入输出流声明输入输出流 streampos posstreampos pos[[ 2020]] ; ; ////声明保存文件指针位置的数组声明保存文件指针位置的数组 myio.open(″myfile″,ios::in|ios::out|ios::binary); myio.open(″myfile″,ios::in|ios::out|ios::binary); //// 以读写方式打开文件以读写方式打开文件 for(int i=0;i<10;i++)for(int i=0;i<10;i++) {{ dbl=i/10.0;dbl=i/10.0; myio.write((char *)&dbl,sizeof(double)); myio.write((char *)&dbl,sizeof(double)); //// 向文件中写数据向文件中写数据 pospos[[ ii]] =myio.tellp(); =myio.tellp(); //// 保存文件指针当前的位置保存文件指针当前的位置 }}

for(i=10;i<20;i++)for(i=10;i<20;i++) {{ dbl=i/10.0;dbl=i/10.0; myio.write((char *)&dbl,sizeof(double)); myio.write((char *)&dbl,sizeof(double)); //// 向文件中写数据向文件中写数据 pospos[[ ii]] =myio.tellp(); =myio.tellp(); //// 保存文件指针当前的位置保存文件指针当前的位置 }} `̀

通过文件指针的位置对文件进行读写操作通过文件指针的位置对文件进行读写操作例 例 11-1011-10

Page 23: 第   11  章 输入/输出流

for(i=0;i<20;i=i+2)for(i=0;i<20;i=i+2) {{ myio.seekg(posmyio.seekg(pos [[ ii]] ); ); //// 移动文件指针位置至指定位置移动文件指针位置至指定位置 myio.read((char *)&dbl,sizeof(double)); myio.read((char *)&dbl,sizeof(double)); ////读数据读数据 cout<<″The data is :″<<dbl<<endl;cout<<″The data is :″<<dbl<<endl; }}

myio.seekp(0,ios::beg); myio.seekp(0,ios::beg); //// 将文件指针置于文件开始将文件指针置于文件开始 for(i=100;i<120;i++)for(i=100;i<120;i++) {{ dbl=i/10.0;dbl=i/10.0; myio.write((char *)&dbl,sizeof(double)); myio.write((char *)&dbl,sizeof(double)); //// 向文件中写数据向文件中写数据 }}

for(i=1;i<20;i=i+2)for(i=1;i<20;i=i+2) {{ myio.seekg(posmyio.seekg(pos [[ ii]] ); ); //// 移动文件指针至指定位置移动文件指针至指定位置 myio.read((char *)&dbl,sizeof(double)); myio.read((char *)&dbl,sizeof(double)); ////从文件中读数据从文件中读数据 cout<<″The data is :″<<dbl<<endl;cout<<″The data is :″<<dbl<<endl; }} return 0;return 0;}}//// 源程序结束源程序结束

(续)(续)

Page 24: 第   11  章 输入/输出流

The data is :0.1The data is :0.1The data is :0.3The data is :0.3The data is :0.5The data is :0.5The data is :0.7The data is :0.7The data is :0.9The data is :0.9The data is :1.1The data is :1.1The data is :1.3The data is :1.3The data is :1.5The data is :1.5The data is :1.7The data is :1.7The data is :1.9The data is :1.9The data is :10.2The data is :10.2The data is :10.4The data is :10.4The data is :10.6The data is :10.6The data is :10.8The data is :10.8The data is :11The data is :11The data is :11.2The data is :11.2The data is :11.4The data is :11.4The data is :11.6The data is :11.6The data is :11.8The data is :11.8

(续)(续)

Page 25: 第   11  章 输入/输出流

C++C++ 语言的语言的 I/OI/O 流库的一个很重要的特性是能够支持新的数据类型——流库的一个很重要的特性是能够支持新的数据类型——用用户自定义的类型的输入和输出。户自定义的类型的输入和输出。

实现这种功能的方式实现这种功能的方式是通过重载插入符是通过重载插入符 <<<< 和提取符和提取符 >>>> ,重载插入符和,重载插入符和提取符的方式与重载其他运算符类似:重载函数具有两个参数,一个是提取符的方式与重载其他运算符类似:重载函数具有两个参数,一个是 osostream(tream( 插入符插入符 )/istream()/istream( 提取符提取符 )) 类的引用,另一个是用户自定义的类的类的引用,另一个是用户自定义的类的引用,该函数的返回也是一个引用,该函数的返回也是一个 ostream(ostream( 插入符插入符 )/istream()/istream( 提取符提取符 )) 类的引类的引用,这样可以保证插入符或者提取符的连续使用。用,这样可以保证插入符或者提取符的连续使用。

//// 源程序开始源程序开始#include <iostream.h>#include <iostream.h>

class Point //class Point // 声明类声明类 PointPoint{{private:private: int x;int x; int y;int y;

例 例 11-1111-11 重载插入符重载插入符 <<<< 和提取符和提取符 >>>>

【【 11.5 11.5 用户自定义类型的输入用户自定义类型的输入 // 输输出出】】

Page 26: 第   11  章 输入/输出流

public:public: Point(int xx=0,int yy=0)Point(int xx=0,int yy=0) {{ x=xx;x=xx; y=yy;y=yy; }} friend istream& operator>>(istream& in, Point& point); friend istream& operator>>(istream& in, Point& point); //// 重载重载 >>>> 为友员为友员 friend ostream& operator<<(ostream& out,Point& point); friend ostream& operator<<(ostream& out,Point& point); //// 重载重载 <<<< 为友员为友员};};

istream& operator>>(istream& in,Point& point)istream& operator>>(istream& in,Point& point)//// 返回返回 istream&istream& 可以保证可以保证 >>>> 的连续使用的连续使用

{{ cout<<″Please input the coordinate of x:″;cout<<″Please input the coordinate of x:″; in>>point.x;in>>point.x; cout<<endl;cout<<endl; cout<<″Please input the coordinate of y:″;cout<<″Please input the coordinate of y:″; in>>point.y;in>>point.y; cout<<endl;cout<<endl; return in;return in;}}

重载插入符重载插入符 <<<< 和提取符和提取符 >>>>例 例 11-1111-11

Page 27: 第   11  章 输入/输出流

ostream& operator<<(ostream& out,Point& point) ostream& operator<<(ostream& out,Point& point) //// 返回返回 ostream&ostream& 可以保证可以保证 <<<< 的连续使用的连续使用

{{ out<<″(″<<point.x<<″,″;out<<″(″<<point.x<<″,″; out<<point.y<<″)″<<endl;out<<point.y<<″)″<<endl; return out;return out;}}

int main()int main(){{ Point myPoint,myPoint1(10,20); Point myPoint,myPoint1(10,20); ////声明类声明类 PointPoint 的对象的对象

cout<<″myPoint(x,y)=″<<myPoint<<endl; cout<<″myPoint(x,y)=″<<myPoint<<endl; //// 自定义数据类型输出自定义数据类型输出 cout<<″myPoint1(x,y)=″<<myPoint1<<endl; cout<<″myPoint1(x,y)=″<<myPoint1<<endl;

cin>>myPoint; cin>>myPoint; //// 自定义数据类型输入自定义数据类型输入 cin>>myPoint1;cin>>myPoint1;

cout<<″the new myPoint(x,y)=″<<myPoint<<endl; cout<<″the new myPoint(x,y)=″<<myPoint<<endl; //// 自定义数据类型输出自定义数据类型输出 cout<<″the new myPoint1(x,y)=″<<myPoint1<<endl;cout<<″the new myPoint1(x,y)=″<<myPoint1<<endl; return 0;return 0;}}//// 源程序结束源程序结束

(续)(续)

Page 28: 第   11  章 输入/输出流

myPoint(x,y)=(0,0)myPoint(x,y)=(0,0)myPoint1(x,y)=(10,20)myPoint1(x,y)=(10,20)Please input the coordinate of x:1Please input the coordinate of x:1Please input the coordinate of y:2Please input the coordinate of y:2Please input the coordinate of x:3Please input the coordinate of x:3Please input the coordinate of y:4Please input the coordinate of y:4the new myPoint(x,y)=(1,2)the new myPoint(x,y)=(1,2)the new myPoint1(x,y)=(3,4)the new myPoint1(x,y)=(3,4)

【【 11.611.6 综合实例综合实例】】

编写程序使之具有学生管理的功能,编写程序使之具有学生管理的功能,并将其保存到并将其保存到 students.datstudents.dat 文件中文件中

Page 29: 第   11  章 输入/输出流

小结C++中使用流的概念实现了输入 /输出的设备无关性。标准输入流 cin、标准输出流 cout分别是 ios类派生类的内置对象,编程者不需要显式定义。可以使用各种输入 /输出成员函数或者操纵子控制数据输入 /输出格式。对文件的输入 /输出需要编程者自己定义对应于该文件的流对象。