1、第8章 文件与数据输入输出,3,教学目标,(1) 了解文件和流的概念; (2) 了解输入输出流类或标准I/O函数库的结构和机制; (3) 了解文件的打开与关闭操作及文件读写的基本方法。,4,基本内容,8.1 输入输出与标准库 8.2 标准输入流 8.3 标准输出流 8.4 文件,5,8.1 输入输出与标准库,标准库构成 标准函数库 从C语言中继承下来 C格式的输入输出函数、字符与字符串处理函数、数学函数、时间日期函数、动态分配函数以及一些实用函数 标准类库 标准C+的I/O流类、字符串类、数字类、异常处理和杂项类以及STL容器类 由编译器厂商提供,与平台、厂商和编译器版本无关,6,输入输出流类
2、库iostream,iostream类库提供了数百种I/O功能,其接口部分分别包含在几个头文件中: 无格式I/O和格式化I/O:头文件iostream 格式化I/O :包含头文件iomanip 文件处理操作 :包含头文件fstream,7,输入/输出流类的继承层次结构,8,8.2 标准输入流,cin是类istream内置的标准流类对象,能构成从键盘到内存的标准输入流。通过流提取运算符“”,变量从流中提取数据。 “”会自动忽略所有的空白字符,因此无法输入包含空格符的字符串。如: char name20; cinname; 假如输入姓名“Tom Hanks”时,变量name中只有“Tom”,9,输
3、入流对象的成员函数get(),这个函数有3种重载形式: cin.get() 用于从指定的输入流中读取一个字符,函数的返回值即为读入的字符。 cin. get(ch) 用于从指定的输入流中读取一个字符,并将该字符赋给字符型变量ch。 cin.get(字符数组buf, 字符个数n, 结束符delim) 用于从指定的输入流中读取n-1个字符,并将这些字符赋给字符数组buf。如果还没有读取完n-1个字符之前就遇到结束符delim,则可提前结束读取过程。结束符delim的默认值为换行符n 。,10,例8-2:包含空格的字符串的输入与输出,#include using namespace std; int
4、 main() char ch1, ch2, ch3, buf150, buf250;cout buf1;cout “使用运算符读取句子:“ buf1 endl;ch1 = cin.get();ch2 = cin.get();cout “使用cin.get()继续读取:“ ch1 endl;cout “使用cin.get()继续读取:“ ch2 endl;cin.get(ch3);cout “使用cin.get(ch3)继续读取:“ ch3 endl;cin.get(buf2, 50);cout “使用cin.get(buf2, 50)继续读取:“ buf2 endl;return 0; ,1
5、1,输入流对象的成员函数,get Extracts characters from the stream up to, but not including, delimiters. getline Extracts characters from the stream (extracts and discards delimiters). read Extracts data from the stream. ignore Extracts and discards characters. peek Returns a character without extracting it from
6、the stream. gcount Counts the characters extracted in the last unformatted operation.,12,8.3 标准输出流,输出流类ostream的标准输出流对象cout通过流插入运算符“”,把变量的值从内存输出到标准输出设备上。 系统会自动根据不同的数据类型采用不同的默认方式输出。 特殊要求的输出格式,需要格式化I/O 使用流操纵符对输出操作进行格式化 使用ios类的格式控制成员函数进行格式化,13,1. 使用流操纵符对输出操作进行格式化,不带参数的流操纵符 endl dec/oct/hex 十/八/十六进制 带参数的
7、流操纵符 (注意:需包含头文件iomanip) setbase(int base) 设置数制转换基数为base setfill(int ch) 将填充字符设置为ch setprecision(int p) 设置数字精度 setw(int w) 将域宽设置为w setiosflags(fmtflags flags) 开启flags中指定的标志 resetiosflags(fmtflags flags) 关闭flags中指定的标志 其中,流格式状态标志字(flags): ios:left 在域中左对齐输出,右边显示填充字符 ios:dec 指定整数应作为十进制(基数10)值 ios:hex 指定整
8、数应作为十六进制(基数16)值 ios:showpos 指定正数和负数前面分别加上+和-号 ios:fixed 指定浮点数以小数方式输出 ios:scientific 指定浮点数输出采用科学记数法,14,例8-4:改变整数的进制,#include using namespace std; int main() int n = 30;cout “整数:“ n endl; cout “以十六进制显示为:“ hex n endl;cout “以十进制显示为:“ dec n endl;cout “以八进制显示为:“ oct n endl;return 0; ,15,例8-3:设置实型数的精度,#inc
9、lude #include #include using namespace std; int main() double r = sqrt( 2.0 );int i;cout “r = “ r endl; / 设置输出为定点小数方式cout setiosflags( ios:fixed) ;cout “以定点小数方式,采用不同精度输出:“ endl;for ( i = 0; i = 4; i+ )cout setprecision( i ) “r = “ r endl;/ 取消定点小数输出方式并设置为科学记数方式cout resetiosflags( ios:fixed) setiosfla
10、gs( ios:scientific) ;cout “以科学记数方式,采用不同精度输出:“ endl;for ( i = 0; i = 4; i+ )cout setprecision( i ) “r = “ r endl;return 0; ,16,例8-5:设置输出宽度、填充字符和对齐方式,#include #include using namespace std; int main() double pi=3.14159;/ 以默认方式输出cout pi endl;/ 设置输出宽度后进行输出cout setw(10) pi endl;/ 使用填充字符并设置输出宽度后进行输出cout se
11、tfill(*) setw(10) pi endl;/ 设置左对齐方式及输出宽度后进行输出cout setiosflags(ios:left) setw(10) pi endl;/ 取消左对齐方式cout resetiosflags(ios:left);/ 设置右对齐方式及输出宽度后进行输出cout setiosflags(ios:right) setw(12) pi endl; return 0; ,17,2. 使用ios类的格式控制成员函数对输出操作进行格式化,格式化函数 width(w) 设置显示字段宽度为w precision(p) 设置浮点数精度为p fill(ch) 设置填充字符为
12、ch setf(flags) 设置输出格式状态为flags unsetf(flags) 清除格式标记flags 其中,流格式状态标志字(flags)同前。,#include using namespace std; int main() cout.precision(4);cout.width(10);cout 10.12345 endl;cout.fill(*);cout.width(10);cout 10.12345 endl;cout.width(10);cout “Hi!“ endl; cout.width(10);cout.setf(ios:left);cout 10.12345en
13、dl;cout.setf(ios:uppercase | ios:scientific);cout 10.12345endl;cout.unsetf(ios:uppercase);cout 10.12345endl;return 0; ,运行结果:10.12 *10.12 *Hi! 10.12* 1.0123E+001 1.0123e+001,19,规 则,成员函数width(w)和流操纵符setw(w)都只对其后的第一个输出项有效用成员函数setf或流操纵符setiosflags设置输出格式后,如果要改为同组另一状态,应调用unsetf或resetiosflags先终止 ios:left i
14、os:right,20,输出流对象的成员函数,put Inserts a single byte into the stream. write Inserts a series of bytes into the stream. flush Flushes the buffer associated with this stream. seekp Changes the streams put pointer. tellp Gets the value of the streams put pointer.,21,8.4 文件,8.4.1 文件和流 8.4.2 文件的打开和关闭 8.4.3 文
15、件的读写,22,8.4.1 文件和流,C+把每一个文件都看成一个有序的字节流,对文件的操作可采用与输入输出流相关的方法。头文件fstream包含了流类ifstream(从文件输入)、ofstream(向文件输出)和fstream(从文件输入输出)的定义。,文件I/O流类的继承层次结构,#include ,23,文件的处理由三个步骤组成:打开文件,数据读写,关闭文件。 1. 打开文件,两种方法: 1)先建立文件流对象,再调用成员函数open()将它与某一个文件关联 ifstream infile; / 输入文件流对象 ofstream outfile; / 输出文件流对象 fstream iof
16、ile; / 输入输出文件流对象outfile.open(“a.dat“); 2)在建立文件流对象的同时通过构造函数来打开文件。如:ofstream outfile (“a.dat“); 测试文件是否被正确打开的方法如下: if ( ! outfile) / 处理文件打开失败情况的代码 2. 关闭文件:成员函数close() outfile.close( );,8.4.2 文件的打开和关闭,24,使用插入与提取运算符对文件进行读写 读文件 写文件 使用类成员函数对文件流进行操作 get读/put写 一次读写一个字节 istream,8.4.3 文件的读写,/ 例8-6:写文件 #include
17、 #include using namespace std; int main() ofstream outfile(“grade.txt“);if(!outfile) cout “文件打开失败!“endl;return 1; outfile “程序设计“ “ “ 95 endl;outfile “大学英语“ “ “ 90.5 endl;outfile “高等数学“ “ “ 93 endl;outfile “普通物理“ “ “ 87.5 endl;outfile.close();return 0; ,/ 例8-7:读文件 #include #include using namespace st
18、d; int main() ifstream infile(“grade.txt“);if(!infile) cout course score;cout course score;cout course score;cout course score;cout course “ “ score endl;infile.close();return 0; ,注意:VC+ 6.0编译器不能正确判断if(! infile),/ 例8-8:使用成员函数get()完成文件读操作 #include #include using namespace std; int main() char ch;int
19、count=0; / 计数器ifstream infile(“grade.txt“);if(!infile) cout =0 ,28,扩展阅读,8.5 二进制文件 二进制文件以位(bit)为单位,整个文件是由0和1组成的无格式的原始数据序列。在二进制方式下的输入输出过程中,系统不对数据进行任何转换。 文本文件以字节(byte)为单位,整个文件实际保存的是一串ASCII字符。可用文字处理器进行编辑。在文本方式下的输入输出过程中,系统进行字符转换。,29,文件打开方式,/ 例8-9:文件拷贝的程序 #include #include using namespace std; int main()
20、char s50, d50;couts;coutd;ifstream infile(s, ios:binary);ofstream outfile(d, ios:binary);if(!infile | !outfile) cout “文件打开失败!“endl;return 1; char ch;while(!infile.eof() ) infile.get (ch); / 成员函数get( )用于从输入流中读取一个字符到变量choutfile.put(ch); / 成员函数put( )将字符变量ch中的字符写到输出流中infile.close();outfile.close();retur
21、n 0; ,31,上机指导,8.5 Visual C+的帮助功能,32,应用举例,例8-10 打开一个由若干个整数组成的文本文件“number.txt”,找出其中所有的质数并存入另一个文本文件“prime.txt”中。例8-11 编写程序,可以读入一个C/C+语言的源文件,并在每一行前面加上行号后保存到另一个名为print.txt的文件中。,/ 例8-10:文件操作 #include #include using namespace std; int isprime(int a) / 素数判别函数 for(int i=2; inum;if(isprime(num) outfilenum“ “;
22、 infile.close();outfile.close();return 0; ,/ 例8-11:源文件加行号 #include #include #include using namespace std; int main() ifstream infile(“test.cpp“);ofstream outfile(“print.txt“);if(!infile | !outfile) cout “文件打开失败!“endl;return 1; char ch;int line = 1;outfile setw(4) line “ “;while(!infile.eof() ) infile.get(ch);if(!infile.eof() outfile ch;if (ch = n) / 当遇到换行时,输出新的行号 line+;outfile setw(4) line “ “; infile.close();outfile.close();return 0; ,35,学好程序设计语言的唯一途径是你的编程能力与你在计算机上投入的时间成,结 束 语,上机练习,正比,