第13章 输入输出流 王雪晶.

Slides:



Advertisements
Similar presentations
C++语言程序设计教程 第5章 构造数据类型 第6章 C++程序的结构.
Advertisements

第 2 章 初探 C++.
補充: Input from a text file
第11章 输入输出流类.
VC++系统开发 第二章 C++语言基础 河北经贸大学信息技术学院.
第4章 数组 数组是由一定数目的同类元素顺序排列而成的结构类型数据 一个数组在内存占有一片连续的存储区域 数组名是存储空间的首地址
流类库与输入/输出 输入/输出标准流类 文件流类 串流类 输入/输出成员函数 用户自定义类型的输入/输出.
第八章 类和对象.
C++的檔案處理 綠園.
資料大樓 --談指標與陣列 綠園.
函數(一) 自訂函數、遞迴函數 綠園.
计算概论 第二十一讲 文件操作 北京大学信息学院.
C++程序设计 第二讲 清华大学软件学院.
第8章 C++输入输出类层次 ffh.
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
第4章 函数与预处理 4.1 概述 4.2 定义函数的一般形式 4.3 函数参数和函数的值 4.4 函数的调用 *4.5 内置函数
教材 《C++程序设计》.谭浩强. 清华大学出版社 王雪晶
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第四章 数组及自定义数据类型 C++语言程序设计.
第一章 程序的基本结构. 第一章 程序的基本结构 教材及授课结构 本章目标 基本内容 扩展阅读 上机指导 应用举例 习题.
C++语言程序设计 C++语言程序设计 第四章 数组及自定义数据类型 C++语言程序设计.
Object-Oriented Programming in C++ 第一章 C++的初步知识
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
第9章 C++的文件操作 “文件”,一般是指内存以外的存储介质上一批数据的集合。C++在语言层次上提供了文件操作的一系列函数用于完成文件的操作,打开、关闭文件,读取、写入文件数据等操作。 1。字符文件与二进制文件 字符文件:又称ASCII文件或文本TEXT文件,它是以一个字节存放一个ASCII码,代表一个字符。例如,32767需要使用5个字节表示,即:
第3章 程序设计初步 第4章 函数与预处理 第5章 数组 第6章 指针 第7章 自定义数据类型
第3讲 C++程序控制结构 3.1 顺序结构 3.2 分支结构 3.3 循环结构 3.4 转向控制 3.5 综合案例分析.
C++语言程序设计 第二章 C++简单程序设计.
第九章 C++的I/O流库 9.1 流 9.2 磁盘文件 9.3 程序举例.
程序的三种基本结构 if条件分支语句 switch多路开关语句 循环语句 循环嵌套 break,continue和goto语句
第八章 文件 引述 输入输出流和文件概述 文件操作 流的格式化输出 程序举例 本章小节.
3 數學運算 3.1 鍵盤輸入 輸入函數cin 多重輸入cin 輸出格式化 3-3
谭浩强 编著 中国高等院校计算机基础教育课程体系规划教材 C++程序设计.
C++语言程序设计 第十一章 流类库与输入/输出.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
切換Dev c++顯示語言 工具->環境選項(V)->介面->language (Chinese TW)
第三节 堆及其应用.
第 14 章 輸出與輸入.
第十三讲 文件流与 输出输入重载.
C++ 程式設計 基礎篇 張啟中 Chang Chi-Chung.
C++大学基础教程 第3章 C++控制语句 北京科技大学 信息基础科学系.
第14章 输入输出与文件 输入输出是指程序与外部设备交换信息 C++把输入输出看成是一个数据流 输入流:外围设备流向内存的数据
第十章 用户自定义数据类型 目录 学生信息管理系统的开发 结构体数据类型的概述 结构体变量的使用 结构体数组
第二章 基本数据类型及运算 C数据类型概述 基本数据类型 运算符和表达式 混合运算与类型转换 数据的输入输出 顺序程序设计举例.
Chapter 2 & Chapter 3.
C++语言程序设计 C++语言程序设计 第五章 函数 第十一组 C++语言程序设计.
第7章 输入/输出流 文件和I/O流概述 标准I/O流的对象及其成员函数 文件流.
第 二 章 数据类型、运算符与表达式.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第三章 控制语句 第十一组 C++语言程序设计.
第3章C++面向对象程序设计 3.1 类和对象 作业1 3.2 继承和派生类 作业2 3.3 多态和虚函数 3.4 运算符重载 作业3
物件導向程式設計 CH2.
C++的檔案處理 綠園.
輸出與輸入(I/O).
第11章 從C到C++語言 11-1 C++語言的基礎 11-2 C++語言的資料型態與運算子 11-3 C++語言的輸出與輸入
C++程式設計入門 變數與運算子 作者:黃建庭.
第十一章 IO流与文件系统 丘志杰 电子科技大学 计算机学院 软件学院.
第2章 基本数据及其运算 本章学习的目标: 1、掌握基本数据的各种表示,基本数据常数的书写方法;
第二讲 基本数据类 型及数组等 此为封面页,需列出课程编码、课程名称和课程开发室名称。
C/C++基礎程式設計班 C++: 物件的使用、參考、重載函式 講師:林業峻 CSIE, NTU 3/28, 2015.
#include <iostream.h>
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
第2章 文件操作 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
第三章 高级函数特性.
C/C++基礎程式設計班 C語言入門、變數、基本處理與輸入輸出 講師:林業峻 CSIE, NTU 3/7, 2015.
C++语言程序设计 C++语言程序设计 第十一章 异常处理 C++语言程序设计.
第9章 C++程序设计初步 9.1 C++的特点 9.2 最简单的C++程序 9.3 C++的输入输出 9.4 函数的重载
變數與資料型態  綠園.
第六章 复合数据类型 指针的声明与使用 数组的声明与使用 指针与数组的相互引用 字符串及相关库函数 new与delete
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
Presentation transcript:

第13章 输入输出流 王雪晶

内容 13.1 C++的输入和输出 13.2 标准输出流 13.3 标准输入流 13.4 文件操作与文件流 13.5 字符串流

13.1 C++的输入和输出 输入输出的含义 C++的I/O对C的发展——类型安全和可扩展性 C++的输入输出流

输入输出的含义 对系统指定的标准设备的输入和输出。 以外存磁盘文件为对象进行输入和输出。 对内存中指定的空间进行输入和输出。

C++的I/O对C的发展——类型安全和可扩展性 在C语言中,用printf和scanf进行输入输出,往往不能保证所输入输出的数据是可靠的、安全的。 在C++的输入输出中,编译系统对数据类型进行严格的检查,凡是类型不正确的数据都不可能通过编译。因此C++的I/O操作是类型安全的。 C++的I/O操作是可扩展的,不仅可以用来输入输出标准类型的数据,也可以用于用户自定义类型的数据。

C++的输入输出流 C++的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一对象。 实际上,在内存中为每一个数据流开辟一个内存缓冲区,用来存放流中的数据。流是与内存缓冲区相对应的。 在C++中,输入输出流被定义为类。C++的I/O库中的类称为流类(stream class)。用流类定义的对象称为流对象。

1. iostream类库中有关的类 C++编译系统提供了用于输入输出的iostream类库。

1. iostream类库中有关的类 C++对文件的输入输出需要用ifstream和ofstream类。

I/O类库中其他类

2. 与iostream类库有关的头文件 头文件是程序与类库的接口,iostream类库的接口分别由不同的头文件来实现。常用的有: fstream用于文件流I/O。 strstream用于字符串流I/O。 stdiostream用于混合使用C和C++的I/O机制时。 iomanip在使用格式化I/O时应包含此头文件。

3. 在iostream头文件中定义的流对象 在iostream头文件中定义的类有ios,istream,ostream,iostream,istream _withassign, ostream_withassign, iostream_withassign等。 iostream头文件包含了对输入输出流进行操作所需的基本信息。 在iostream头文件定义了4种流对象 cin是istream的派生类istream_withassign的对象。 cout是ostream的派生类ostream_withassign的对象。 cerr和clog

4. 在iostream头文件中重载运算符 “<<”和“>>” 在iostream头文件中对它们进行了重载。 如 ostream operator << (int ); ostream operator << (float ); ostream operator << (char ); ostream operator << (char *);

13.2 标准输出流 标准输出流是流向标准输出设备(显示器)的数据。 3个输出流对象: cout, cerr, clog。

1. cout流对象(console output) 未对用户声明的类型数据的输入输出进行重载

2. cerr流对象 cerr流对象是标准错误流。 cerr流中的信息只能在显示器输出。 例, 有一元二次方程ax2+bx+c=0,其一般解为x1,2=(-b±b2-4ac)/2a,但若a=0,或b2-4ac<0时,用此公式出错。

#include <iostream> #include <cmath> using namespace std; int main( ) {float a,b,c,disc; cout<<″please input a,b,c:″; cin>>a>>b>>c; if (a==0) cerr<<″a is equal to zero,error!″<<endl; else if ((disc=b*b-4*a*c)<0) cerr<<″disc=b*b-4*a*c<0″<<endl; else { cout<<″x1=″<<(-b+sqrt(disc))/(2*a)<<endl; cout<<″x2=″<<(-b-sqrt(disc))/(2*a)<<endl; } return 0;

运行情况如下: ① please input a,b,c: 0 2 3↙ a is equal to zero,error! sc=b*b-4*a*c<0 ③please input a,b,c: 1 2.5 1.5↙ x1=-1 x2=-1.5

3. clog流对象(console log) clog流对象也是标准错误流 在终端显示器上显示出错信息。 cerr和clog区别: clog中的信息存放在缓冲区中,缓冲区满后或遇endl时向显示器输出。

格式化输出 使用控制符的方法; 使用流对象的有关成员函数。

1. 使用控制符方式 控制符是在头文件iomanip中定义

#include <iostream> #include <iomanip>//不要忘记包含此头文件 using namespace std; int main() { int a; cout<<″input a:″; cin>>a; cout<<″dec:″<<dec<<a<<endl; //以十进制形式输出整数 cout<<″hex:″<<hex<<a<<endl; cout<<″oct:″<<setbase(8)<<a<<endl; char *pt=″China″; //pt指向字符串″China″ cout<<setw(10)<<pt<<endl; //指定域宽为10,输出字符串 cout<<setfill(′*′)<<setw(10)<<pt<<endl; double pi=22.0/7.0; //计算pi值 cout<<setiosflags(ios::scientific)<<setprecision(8); cout<<″pi=″<<pi<<endl; //输出pi值 cout<<″pi=″<<setprecision(4)<<pi<<endl; //改为4位小数 cout<<″pi=″<<setiosflags(ios::fixed)<<pi<<endl; return 0; }

运行结果如下: input a:34↙(输入a的值) dec:34 (十进制形式) hex:22 (十六进制形式) oct:42 (八进制形式) China (域宽为10) *****China (域宽为10,空白处以′*′填充) pi=3.14285714e+00 (指数形式输出,8位小数) pi=3.1429e+00 (指数形式输出,4位小数) pi=3.143 (小数形式输出,精度仍为4)

2. 用流对象的成员函数 流成员函数setf() 控制符setiosflags()。 格式标志在类ios中被定义为枚举值。

#include <iostream> using namespace std; int main( ) { int a=21; cout.setf(ios::showbase);//显示基数符号(0x或0) cout<<″dec:″<<a<<endl; //默认以十进制形式输出a cout.unsetf(ios::dec); //终止十进制的格式设置 cout.setf(ios::hex); //设置以十六进制输出的状态 cout<<″hex:″<<a<<endl; //以十六进制形式输出a cout.unsetf(ios::hex); //终止十六进制的格式设置 cout.setf(ios::oct); //设置以八进制输出的状态 cout<<″oct:″<<a<<endl; //以八进制形式输出a cout.unsetf (ios::oct); char *pt=″China″; //pt指向字符串″China″ cout.width(10); //指定域宽为10

cout<<pt<<endl; //输出字符串 cout.width(10); //指定域宽为10 cout.fill(′*′); //指定空白处以′*′填充 double pi=22.0/7.0; //输出pi值 cout.setf(ios::scientific); //指定用科学记数法输出 cout<<″pi=″; //输出″pi=″ cout.width(14); //指定域宽为14 cout<<pi<<endl; //输出pi值 cout.unsetf(ios::scientific); //终止科学记数法状态 cout.setf(ios::fixed); //指定用定点形式输出 cout.width(12); //指定域宽为12 cout.setf(ios::showpos); //正数输出“+”号 cout.setf(ios::internal); //数符出现在左侧 cout.precision(6); //保留6位小数 cout<<pi<<endl; //输出pi,注意数符“+”的位置 return 0; }

运行情况如下: dec:21(十进制形式) hex:0x15 (十六进制形式,以0x开头) oct:025 (八进制形式,以0开头) China (域宽为10) *****China (域宽为10,空白处以′*′填充) pi=**3.142857e+00 (指数形式输出,域宽14,默认6位小数) +***3.142857 (小数形式输出,精度为6,最左侧输出数符“+”)

用流成员函数put输出字符 如: cout.put(′a′); 参数可以是字符或ASCII码 cout.put(65+32); cout.put(71).put(79).pu(79).put(68).put(′\n′); GOOD。

例13.4 有一个字符串″BASIC″,要求把它们按相反的顺序输出。 #include <iostream> using namespace std; int main( ) {char *a=″BASIC″;//字符指针指向′B′ for(int i=4;i>=0;i--) cout.put(*(a+i)); //从最后一个字符开始输出 cout.put(′\n′); return 0; }

13.3 标准输入流 标准输入流是从标准输入设备(键盘)流向程序的数据。

13.3.1 cin流 cin是istream类的对象,程序中的变量通过流提取符“>>”从流中提取数据。 流提取符“>>”从流中提取数据时通常跳过输入流中的空格、tab键、换行符等空白字符。 输入流cin处于出错状态:当遇到无效字符或遇到文件结束符。 cin值为0

例13.5 通过测试cin的真值,判断流对象是否处于正常状态。 #include <iostream> using namespace std; int main( ) {float grade; cout<<″enter grade:″; while(cin>>grade) { if(grade>=85) cout<<grade<<″GOOD!″<<endl; if(grade<60) cout<<grade<<″fail!″<<endl; } cout<<″The end.″<<endl; return 0;

13.3.2 用于字符输入的流成员函数 get 无参数 一个参数 三个参数 getline

1. 用get函数读入一个字符 (1) 无参数的get函数 其调用形式为 cin.get()

例13.6 用get函数读入字符。 运行情况如下: #include <iostream> int main( ) {int c; cout<<″enter a sentence:″<<endl; while((c=cin.get())!=EOF) cout.put(c); return 0; } 运行情况如下: enter a sentence: I study C++ very hard.↙(输入一行字符) I study C++ very hard. (输出该行字符) ^Z↙(程序结束)

1. 用get函数读入一个字符 (2) 一个参数的get函数 其调用形式为 cin.get(ch)

#include <iostream> int main( ) { char c; cout<<″enter a sentence:″<<endl; while(cin.get(c)) { cout.put(c);} cout<<″end″<<endl; return 0; }

(3) 三个参数的get函数 其调用形式为 cin.get(字符数组,字符个数n,终止字符) 或

运行情况如下: #include <iostream> using namespace std; int main( ) {char ch[20]; cout<<″enter a sentence:″<<endl; cin.get(ch,10,′\n′);//指定换行符为终止字符 cout<<ch<<endl; return 0; } 运行情况如下: enter a sentence: I study C++ very hard.↙ I study C

2. getline函数读入一行字符 其用法与带3个参数的get函数类似。 cin.getline(字符数组(或字符指针),字符个数n,终止标志)

例13.7 用getline函数读入一行字符。 #include <iostream> using namespace std; int main( ) {char ch[20]; cout<<″enter a sentence:″<<endl; cin>>ch; cout<<″The string read with cin is:″<<ch<<endl; cin.getline(ch,20,′/′);//读19个字符或遇′/′结束 cout<<″The second part is:″<<ch<<endl; cin.getline(ch,20); //读19个字符或遇′\n′结束 cout<<″The third part is:″<<ch<<endl; return 0; }

程序运行情况如下: cin>>ch; cin.getline(ch,20,′/′); cin.getline(ch,20); enter a sentence: I like C++./I study C++./I am happy.↙ The string read with cin is:I The second part is: like C++. The third part is:I study C++./I am h

13.3.3 istream类的其他成员函数 1. eof 函数

运行情况如下: 例13.8 逐个读入一行字符,将非空格字符输出。 #include <iostream> using namespace std; int main( ) {char c; while(!cin.eof( )) //eof( )为假表示未遇到文件结束符 { if((c=cin.get( ))!=′ ′) cout.put(c); } return 0; } 运行情况如下: C++ is very interesting.↙ C++isveryinteresting. ^Z(结束)

2. peek函数 peek函数的作用是观测下一个字符。 c=cin.peek( );

3. putback函数 其调用形式为 cin.putback(ch); 其作用是将前面用get或getline函数读取的字符ch返回到输入流,插入到当前指针位置,以供后面读取。

例13.9 peek函数和putback函数的用法。 #include <iostream> using namespace std; int main( ) {char c[20]; int ch; cout<<″please enter a sentence:″<<endl; cin.getline(c,15,′/′); cout<<″The first part is:″<<c<<endl; ch=cin.peek( );//观看当前字符 cout<<″The next character(ASCII code) is:″<<ch<<endl; cin.putback(c[0]); //将′I′插入到指针所指处 cout<<″The second part is:″<<c<<endl; return 0; }

运行情况如下: please enter a sentence: I am a boy./ am a student./↙ The first part is:I am a boy. The next character(ASCII code) is:32(下一个字符是空格) The second part is:I am a student

4. ignore函数 其调用形式为 cin,ignore(n, 终止字符) 如 ighore(5, ′A′) 不带参数或只带一个参数。如 ignore( )(n默认值为1,终止字符默认为EOF) 相当于 ignore(1,EOF)

运行结果如下: 例13.10用ignore函数跳过输入流中的字符。 先看不用ignore函数的情况: #include <iostream> using namespace std; int main( ) {char ch[20]; cin.get(ch,20,′/′); cout<<″The first part is:″<<ch<<endl; cout<<″The second part is:″<<ch<<endl; return 0; } 运行结果如下: I like C++./I study C++./I am happy.↙ The first part is:I like C++. The second part is:(字符数组ch中没有从输入流中读取有效字符)

用ignore函数,将程序改为 运行结果如下: #include <iostream> using namespace std; int main( ) {char ch[20]; cin.get(ch,20,′/′); cout<<″The first part is:″<<ch<<endl; cin.ignore( );//跳过输入流中一个字符 cout<<″The second part is:″<<ch<<endl; return 0; } 运行结果如下: I like C++./I study C++./I am happy.↙ The first part is:I like C++. The second part is:I study C++.

13.4 文件操作与文件流 13.4.1 文件的概念 13.4.2 文件流类与文件流对象 13.4.3 文件的打开与关闭 13.4.4 对ASCII文件的操作

13.4.1 文件的概念 对用户来说,文件有两大类 根据文件中数据的组织形式,可分为 一类是程序文件。 一类是数据文件。程序中的输入和输出的对象就是数据文件。 根据文件中数据的组织形式,可分为 ASCII文件 二进制文件

对于字符信息,在内存中是以ASCII代码形式存放的,因此,无论用ASCII文件输出还是用二进制文件输出,其数据形式是一样的。 对于数值数据,二者是不同的。例如有一个长整数100000,在内存中占4个字节。

13.4.1 文件的概念 高级的I/O功能 低级的I/O功能 把若干个字节组合为一个有意义的单位,然后以ASCII字符形式输入和输出。 以字节为单位输入和输出的,在输入和输出时不进行数据格式的转换。

13.4.2 文件流类与文件流对象 文件流是以外存文件为输入输出对象的数据流。 输出文件流是从内存流向外存文件的数据; 输入文件流是从外存文件流向内存的数据。

13.4.2 文件流类与文件流对象 (1) ifstream类,从istream类派生的。 用来支持从磁盘文件的输入。 (2) ofstream类,从ostream类派生的。 用来支持向磁盘文件的输出。 (3) fstream类,从iostream类派生的。 用来支持对磁盘文件的输入输出。

13.4.2 文件流类与文件流对象 建立一个输出文件流对象: ofstream outfile; 还未指定它向哪一个磁盘文件输出。

13.4.3 文件的打开与关闭 1. 打开磁盘文件 (1) 为文件流对象和指定的磁盘文件建立关联。 (2) 指定文件的工作方式。 以上工作可以通过两种不同的方法实现。 (1) 调用文件流的成员函数open。如 ofstream outfile; outfile.open(″f1.dat″,ios::out); 文件流对象.open(磁盘文件名,输入输出方式);

13.4.3 文件的打开与关闭 (2) 在定义文件流对象时指定参数 文件流类定义了带参数的构造函数。 如 ostream outfile(″f1.dat″,ios::out);

13.4.3 文件的打开与关闭 2. 关闭磁盘文件 关闭文件用成员函数close。如 outfile.close( );

13.4.4 对ASCII文件的操作 每一个字节中均以ASCII代码形式存放数据。 对ASCII文件的读写操作可以用以下两种方法: (1) 用 “<<”和 “>>” 。 (2) 用文件流的put,get,getline等成员函数进行字符的输入输出。

例13.11 有一个整型数组,含10个元素,从键盘输入10个整数给数组,将此数组送到磁盘文件中存放。 #include <fstream> using namespace std; int main( ) {int a[10]; ofstream outfile(″f1.dat″,ios::out); if(!outfile) //如果打开失败,outfile返回0值 { cerr<<″open error!″<<endl; exit(1); } cout<<″enter 10 integer numbers:″<<endl; for(int i=0;i<10;i++) { cin>>a[i]; outfile<<a[i]<<″ ″;} //向磁盘文件″f1.dat″输出数据 outfile.close(); //关闭磁盘文件″f1.dat″ return 0; }

例13.12 从例13.11建立的数据文件f1.dat中读入10个整数放在数组中,找出并输出10个数中的最大者和它在数组中的序号。 #include <fstream> int main( ) {int a[10],max,i,order; ifstream infile(″f1.dat″,ios::in|ios::nocreate); if(!infile) {cerr<<″open error!″<<endl; exit(1); } for(i=0;i<10;i++) {infile>>a[i]; cout<<a[i]<<″ ″;} //在显示器上顺序显示10个数 cout<<endl; max=a[0];

运行情况如下: order=0; for(i=1;i<10;i++) if(a[i]>max) { max=a[i]; //将当前最大值放在max中 order=i; //将当前最大值的元素序号放在order中 } cout<<″max=″<<max<<endl<<″order=″<<order<<endl; infile.close(); return 0; 运行情况如下: 1 3 5 2 4 6 10 8 7 9(在磁盘文件中存放的10个数) max=10 (最大值为10) order=6 (最大值是数组中序号为6的元素)

例13. 13 从键盘读入一行字符,把其中的字母字符依次存放在磁盘文件f2 例13.13 从键盘读入一行字符,把其中的字母字符依次存放在磁盘文件f2.dat中。再把它从磁盘文件读入程序,将其中的小写字母改为大写字母,再存入磁盘文件f3.dat。 #include <fstream> using namespace std; void save_to_file( ) { ofstream outfile(″f2.dat″); if(!outfile) { cerr<<″open f2.dat error!″<<endl; exit(1); } char c[80]; cin.getline(c,80);

for(int i=0;c[i]!=0;i++) if(c[i]>=65 && c[i]<=90||c[i]>=97 && c[i]<=122)//如果是字母 { outfile.put(c[i]); //将字母字符存入磁盘文件f2.dat cout<<c[i];} //同时送显示器显示 cout<<endl; outfile.close(); //关闭f2.dat } //从磁盘文件f2.dat读入字母字符,将其中的小写字母改为大写字母,再存入f3.dat void get_from_file() { char ch; ifstream infile(″f2.dat″,ios::in|ios::nocreate); if(!infile) {cerr<<″open f2.dat error!″<<endl; exit(1);

ofstream outfile(″f3.dat″); if(!outfile) {cerr<<″open f3.dat error!″<<endl; exit(1); } while(infile.get(ch)) {if(ch>=97 && ch<=122) //判断ch是否为小写字母 ch=ch-32; //将小写字母变为大写字母 outfile.put(ch); //将该大写字母存入磁盘文件f3.dat cout<<ch; //同时在显示器输出 cout<<endl; infile.close( ); //关闭磁盘文件f2.dat outfile.close(); //关闭磁盘文件f3.dat

int main( ) {save_to_file( ); get_from_file( ); return 0; } 运行情况如下: New Beijing, Great Olypic, 2008, China.↙ NewBeijingGreatOlypicChina(将字母写入磁盘文件f2.dat,同时在屏幕显示) NEWBEIJINGGREATOLYPICCHINA (改为大写字母)

13.4.5 对二进制文件的操作 又称为内存数据的映像文件。 对二进制文件的操作也需要先打开文件,用完后要关闭文件。 在打开时要用ios::binary指定为以二进制形式传送和存储。

1. 用成员函数read和write读写二进制文件 对二进制文件的读写主要用istream类的成员函数read和write来实现。 istream& read(char *buffer,int len); ostream& write(const char * buffer,int len); 调用的方式为 a. write(p1,50); b. read(p2,30);

例13.14 将一批数据以二进制形式存放在磁盘文件中。 #include <fstream> using namespace std; struct student {char name[20]; int num; int age; char sex; }; int main( ) {student stud[3]={″Li″,1001,18,′f′,″Fun″,1002,19,′m′,″Wang″,1004,17,′f′};

ofstream outfile(″stud.dat″,ios::binary); if(!outfile) {cerr<<″open error!″<<endl; abort( );//退出程序 } for(int i=0;i<3;i++) outfile.write((char*)&stud[i],sizeof(stud[i])); outfile.close( ); return 0;

例13.15 将刚才以二进制形式存放在磁盘文件中的数据读入内存并在显示器上显示。 #include <fstream> using namespace std; struct student {string name; int num; int age; char sex; }; int main( ) {student stud[3]; int i;

ifstream infile(″stud.dat″,ios::binary); if(!infile) {cerr<<″open error!″<<endl; abort( ); } for(i=0;i<3;i++) infile.read((char*)&stud[i],sizeof(stud[i])); infile.close( ); {cout<<″NO.″<<i+1<<endl; cout<<″name:″<<stud[i].name<<endl; cout<<″num:″<<stud[i].num<<endl;; cout<<″age:″<<stud[i].age<<endl; cout<<″sex:″<<stud[i].sex<<endl<<endl; return 0;

2. 与文件指针有关的流成员函数 说明: (1) 这些函数名的第一个字母或最后一个字母不是g就是p。 (2) 函数参数 “文件中的位置”和“位移量” 指定为long型整数,以字节为单位。 “参照位置”可以是下面三者之一: ios::beg文件开头,这是默认值。 ios::cur指针当前的位置。 ios::end文件末尾。

举例如下: infile.seekg(100); infile.seekg(-50,ios::cur); outfile.seekp(-75,ios::end);

3. 随机访问二进制数据文件 例13.16 有5个学生的数据,要求: (1) 把它们存到磁盘文件中; (2) 将磁盘文件中的第1,3,5个学生数据读入程序,并显示出来; (3) 将第3个学生的数据修改后存回磁盘文件中的原有位置。 (4) 从磁盘文件读入修改后的5个学生的数据并显示出来。

3. 随机访问二进制数据文件 要实现以上要求,需要解决3个问题: (1) 由于同一磁盘文件在程序中需要频繁地进行输入和输出,因此可将文件的工作方式指定为输入输出文件,即ios::in|ios::out|ios::binary。 (2) 正确计算好每次访问时指针的定位,即正确使用seekg或seekp函数。 (3) 正确进行文件中数据的重写(更新)。

#include <fstream> using namespace std; struct student {int num; char name[20]; float score; }; int main( ) {student stud[5]={1001,″Li″,85,1002,″Fun″,97.5,1004,″Wang″,54, 1006,″Tan″,76.5,1010,″ling″,96}; fstream iofile(″stud.dat″,ios::in|ios::out|ios::binary); if(!iofile) {cerr<<″open error!″<<endl; abort( ); }

for(int i=0;i<5;i++)//向磁盘文件输出5个学生的数据 iofile.write((char *)&stud[i],sizeof(stud[i])); student stud1[5]; //用来存放从磁盘文件读入的数据 for(int i=0;i<5;i=i+2) {iofile.seekg(i*sizeof(stud[i]),ios::beg); iofile.read((char *)&stud1[i/2],sizeof(stud1[0])); cout<<stud1[i/2].num<<“”<<stud1[i/2].name<<″ ″<<stud1[i/2].score<<endl; } cout<<endl;

stud[2].num=1012; //修改第3个学生(序号为2)的数据 strcpy(stud[2].name,″Wu″); stud[2].score=60; iofile.seekp(2*sizeof(stud[0]),ios::beg); iofile.write((char *)&stud[2],sizeof(stud[2])); //更新第3个学生数据 iofile.seekg(0,ios::beg); //重新定位于文件开头 for(int i=0;i<5;i++) {iofile.read((char *)&stud[i],sizeof(stud[i])); //读入5个学生的数据 cout<<stud[i].num<<″ ″<<stud[i].name<<″ ″<<stud[i].score<<endl; } iofile.close( ); return 0;

13.5 字符串流 字符串流以内存中用户定义的字符数组(字符串)为输入输出的对象,字符串流也称为内存流。 在字符数组中可以存放字符,也可以存放整数、浮点数以及其他类型的数据。

13.5 字符串流 字符串流类有istrstream,ostrstream和strstream。 字符串流与文件文件流有3点不同: (1) 输出时数据流向内存中的一个存储空间。输入时从内存中的存储空间读取数据。 (2) 字符串流对象关联是内存中的一个字符数组。 (3) 字符串流所关联的字符数组中没有相应的结束标志,用户要指定一个特殊字符作为结束符。

ostrstream strout(ch1,20); 1. 建立输出字符串流对象 ostrstream类提供的构造函数的原型为 ostrstream::ostrstream(char *buffer, int n, int mode=ios::out); 建立输出字符串流对象并与字符数组建立关联: ostrstream strout(ch1,20);

2. 建立输入字符串流对象 建立输入字符串流对象: istrstream类提供了两个带参的构造函数: istrstream::istrstream(char *buffer); istrstream::istrstream(char *buffer,int n); 建立输入字符串流对象: istrstream strin(ch2); istrstream strin(ch2,20);

3. 建立输入输出字符串流对象 strstream类提供的构造函数的原型为 strstream::strstream(char *buffer,int n,int mode); 建立输入输出字符串流对象: strstream strio(ch3,sizeof(ch3),ios::in|ios::out);

例13.17 将一组数据保存在字符数组中。 #include <strstream> using namespace std; struct student {int num; char name[20]; float score; } int main( ) {student stud[3]={1001,″Li″,78,1002,″Wang″,89.5,1004,″Fun″,90}; char c[50];//用户定义的字符数组

ostrstream strout(c,30); for(int i=0;i<3;i++) //向字符数组c写3个学生的数据 strout<<stud[i].num<<stud[i].name<<stud[i].score; strout<<ends; cout<<″array c:″<<c<<endl; //显示字符数组c中的字符 } 运行时在显示器上的输出如下: array c: 1001Li781002Wang89.51004Fun90

例13.18 在一个字符数组c中存放了10个整数,以空格相间隔,要求将它们放到整型数组中,再按大小排序,然后再存放回字符数组c中。 #include <strstream> using namespace std; int main( ) {char c[50]=″12 34 65 -23 -32 33 61 99 321 32″; int a[10],i,j,t; cout<<″array c:″<<c<<endl;//显示字符数组中的字符串 istrstream strin(c,sizeof(c)); for(i=0;i<10;i++) strin>>a[i]; //从字符数组c读入10个整数赋给整型数组a cout<<″array a:″; cout<<a[i]<<″ ″; //显示整型数组a各元素 cout<<endl;

运行结果如下: for(i=0;i<9;i++) //用起泡法对数组a排序 for(j=0;j<9-i;j++) if(a[j]>a[j+1]) {t=a[j];a[j]=a[j+1];a[j+1]=t;} ostrstream strout(c,sizeof(c)); for(i=0;i<10;i++) strout<<a[i]<<″ ″; //将10个整数存放在字符数组c strout<<ends; //加入′\\0′ cout<<″array c:″<<c<<endl; //显示字符数组c return 0; } 运行结果如下: array c: 12 34 65 -23 -32 33 61 99 321 32(字符数组c原来的内容) array a: 12 34 65 -23 -32 33 61 99 321 32 (整型数组a的内容) array c: -32 –23 12 32 33 34 61 65 99 321 (字符数组c最后的内容)