13_fstream

输入输出流(在 C++ 中,所有的输入输出都通过“流”来描述。输入流:数据流向程序 (input) 输出流:数据从程序中流出 (output) 具体实现方法:流类和流对象) 重载 << 和 >> (IO 标准库分别使用 << 和 >> 执行输出和输入操作,为了使得它们也适用于新定义的类,即也能用 << 和 >> 进行相应对象的输出和输入,需要对这两个运算符进行重载。)
展开查看详情

1.第十三讲 文件 流与 输出 输入重载

2.2 输入输出流 文件流类与文件流对象 文件流对象与文件关联 文件读写: 文本文件与二进制文件 重载输出输入操作运算符 &lt;&lt; 和 &gt;&gt; 在 C++ 中,所有的输入输出都通过“ 流 ”来描述。 输入流 :数据流向程序 (input) 输出流 :数据从程序中流出 (output) 具体实现方法: 流类 和 流对象

3.类名 作用 头文件 ios 抽象父类 iostream istream ostream iostream 通用输入流和其他输入流的父类 通用输出流和其他输出流的父类 通用输入输出流和其他输入输出流的父类 iostream C++ I/O 库 中定义的流类 3 ifstream ofstream fstream 输入文件流类 输出文件流类 输入输出文件流类 fstream ios istream ostream ifstream ofstream iostream fstream

4. 文件流头文件: fstream #include &lt; fstream &gt; 该头文件中定义了三个文件流类 ofstream 向文件写入数据 ifstream 从文件读取数据 fstream 既读又写 文件流类 4

5.fstream fstrm ; // 创建一个文件流对象,未绑定到任何文件 fstream fstrm ( fname ); // 创建一个文件流,并绑定到文件 fname fstream fstrm ( fname , mode); // 创建文件流的同时指定文件的打开模式 这里的类 fstream 也可以是 ifstream 或 ofstream 如果用 ifstream , 则对象所关联的文件只能读 如果 用 ofstream , 则对象所关联的文件只能写 创建文件流对象 5

6. 文件流对象基本操作(成员函数) fstrm.open ( fname ) // 将文件流对象 fstrm 绑定到文件 fname fstrm.close () // 关闭与文件流对象 fstrm 绑定的文件 fstrm.is_open () // 测试文件是否已顺利打开(且未关闭) 将文件流对象关联到其它文件时,须先关闭已绑定的文件 文件流对象被释放时, close 会被自动调用 文件流成员函数 6

7.ios ::in // 只读 ios ::out // 只写,若文件存在,则内容被清除 ios ::app // 追加,即每次写操作均定位到文件末尾 ios ::ate // 打开文件后立即定位到文件末尾 ios :: Trunc // 若文件存在,则清除文件中原有的内容 ios ::binary // 以二进制方式进行读写 输入输出 方式是 在 ios 类 中 定义的 以上 方式可以组合使用 ,用“ | ”隔开,如 ios :: out|ios ::binary ios ::app 通常与 ios ::out 组合使用 文件打开模式 7

8. 在 缺省情形下,文件以 文本方式 打开 ifstream 对象只能设定 in 模式,缺省为 in ofstream 对象只能设定 out 模式,缺省为 out fstream 对象可以设定 in 或 / 和 out 模式 文件打开模式(续) 8 建议使用 fstream 对象进行文件读写操作。 ifstream ifstrm ; ofstream ofstrm ; fstream fstrm ; ifstrm.open (" fname1 "); // 以缺省方式打开 ofstrm.open ("fname2", ios ::out ); fstrm.open ("fname3", ios :: out|ios ::app );

9. 文本文件的写: &lt;&lt; fstream fstrm ("fname.txt", ios ::out); fstrm &lt;&lt; "Hello Math!" &lt;&lt; endl ; fstrm &lt;&lt; "This is an example" &lt;&lt; endl ; fstrm.close (); 文本文件的 读 : &gt;&gt; 或 getline char str1[20], str2[20]; fstream fstrm ("fname.txt", ios ::in); fstrm &gt;&gt; str1; // 缺省以空格为输入结束符 fstrm.getline (str2,12); fstrm.close (); 我们是如何使用 cin 和 cout 的, 就可以同样来使用文件流对象 ex13_fstream01.cpp 文本文件操作 9

10.对二进制文件使用 &lt;&lt; 、 &gt;&gt; 或 getline 是没有意义的 。 此时需要使用父类 ostream 的成员函数 write 和父类 istream 的成员函数 read 。 write 和 read 的函数原型 write( const char* buf , int n); read(char* buf , int n); 10 二进制文件操作 字符指针 buf 指向 内存中一段存储空间 。 n 是 读写的字节数 。

11.输出文件流对象 .write(buf,50); 11 二进制文件操作(续) write 函数 将字符 指针 buf 所指定的 地址开始 的 50 个 字节的内容不加转换地写 到输出文件流对象中。 read 函数 从 输入文件流对象 所 关联 的文件 中, 读入 30 个 字节 ( 或 遇 EOF 结束 ),存放在字符 指针 buf 所 指 的内存空间 内 。 输入 文件流对象 .read(buf,30 );

12.例: 二进制文件操作 const int n=5; int A[n]={1,2,3,4,5}; fstream fstrm ("fout. dat ", ios :: out|ios ::binary) ; // 文件流对象可以直接初始化 fstrm.write ( (char*) A,sizeof (A)); // 需要强制类型转换 fstrm.close (); int B[n]; fstrm.open ("fout. dat ", ios :: in|ios ::binary); fstrm.read ( (char*) B,sizeof (B)); fstrm.close (); ex13_fstream02.cpp 12

13.13 重载 &lt;&lt; 和 &gt;&gt; IO 标准库分别使用 &lt;&lt; 和 &gt;&gt; 执行 输出 和 输入 操作,为了 使得它们也 适用于新定义的类 ,即也能 用 &lt;&lt; 和 &gt;&gt; 进行 相应对象的输出和输入,需要对这两个运算符进行重载。

14.重载 &lt;&lt; 和 &gt;&gt; 14 class Rational { public: Rational() { x=0; y=1; } Rational( int x, int y) { this-&gt;x=x; this-&gt;y=y; } friend ostream &amp; operator&lt;&lt;( ostream &amp;, const Rational &amp;); friend istream &amp; operator&gt;&gt;( istream &amp;, Rational &amp;); private: int x, y; }; 我们通过具体例子来说明 注:不能作为成员函数重载!只能作为非成员函数!

15.几点说明 15 通常情况下,第一个形参是 ostream 对象 的 引用 ( 非常量 ) ( 非常量 :需要修改; 引用 :无法直接复制一个 ostream 对象) 第二个形参是 对象的常引用 (需要输出的对象) 为了与其他输出运算符保持一致,一般返回它的 ostream 形参 friend ostream &amp; operator&lt;&lt;( ostream &amp;, const Rational &amp;); ostream &amp; operator&lt;&lt;( ostream &amp; out, const Rational &amp; a) { out &lt;&lt; a.x &lt;&lt; "/" &lt;&lt; a.y ; return out; } ex13_overload11.cpp 注:尽量减少格式化操作!如换行等

16.16 上机作业 2) 重载复数类的输出操作符 &lt;&lt; 和输入操作符 &gt;&gt; 输出格式为: a+bi , 如: 3+4i ( 程序命名为 hw13_02.cpp ) 1) 用 文件流方式完成下面 操作: 生成 一个 6 X 6 的矩阵 A ,其元素为 [0,1] 之间的双精度数。 ( a) 将其按矩阵形式写入到一个 文本文件 fout01.txt 中; ( b) 将其写入到一个 二进制文件 fout01.dat 中; ( c) 再从文件 fout01.dat 中读取 前 12 个 数据( 双精度 ), 构成一个 2 X 6 的矩阵 B ,并将 B 按行输出。 (程序命名为 hw13_01.cpp )