1 / 35

第 8 章 文件与数据输入输出

第 8 章 文件与数据输入输出. 教学目标. (1) 了解文件和流的概念; (2) 了解输入输出流类或标准I/O函数库的结构和机制; (3) 了解文件的打开与关闭操作及文件读写的基本方法。. 基本内容. 8.1 输入输出与标准库 8.2 标准输入流 8.3 标准输出流 8.4 文件. 8.1 输入输出与标准库. 标准库构成 标准函数库 从 C 语言中继承下来 C 格式的输入输出函数、字符与字符串处理函数、数学函数、时间日期函数、动态分配函数以及一些实用函数 标准类库 标准 C++ 的 I/O 流类、字符串类、数字类、异常处理和杂项类以及 STL 容器类

ike
Télécharger la présentation

第 8 章 文件与数据输入输出

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第8章 文件与数据输入输出

  2. 教学目标 • (1) 了解文件和流的概念; • (2) 了解输入输出流类或标准I/O函数库的结构和机制; • (3) 了解文件的打开与关闭操作及文件读写的基本方法。

  3. 基本内容 • 8.1 输入输出与标准库 • 8.2 标准输入流 • 8.3 标准输出流 • 8.4 文件

  4. 8.1 输入输出与标准库 • 标准库构成 • 标准函数库 • 从C语言中继承下来 • C格式的输入输出函数、字符与字符串处理函数、数学函数、时间日期函数、动态分配函数以及一些实用函数 • 标准类库 • 标准C++的I/O流类、字符串类、数字类、异常处理和杂项类以及STL容器类 • 由编译器厂商提供,与平台、厂商和编译器版本无关

  5. 输入输出流类库iostream • iostream类库提供了数百种I/O功能,其接口部分分别包含在几个头文件中: • 无格式I/O和格式化I/O:头文件iostream • 格式化I/O :包含头文件iomanip • 文件处理操作 :包含头文件fstream

  6. ios istream ostream ifstream iostream ofstream fstream 输入/输出流类的继承层次结构

  7. 8.2 标准输入流 • cin是类istream内置的标准流类对象,能构成从键盘到内存的标准输入流。通过流提取运算符“>>”,变量从流中提取数据。 • “>>”会自动忽略所有的空白字符,因此无法输入包含空格符的字符串。如: char name[20]; cin>>name; • 假如输入姓名“Tom Hanks”时,变量name中只有“Tom”

  8. 输入流对象的成员函数get() • 这个函数有3种重载形式: • cin.get() • 用于从指定的输入流中读取一个字符,函数的返回值即为读入的字符。 • cin. get(ch) • 用于从指定的输入流中读取一个字符,并将该字符赋给字符型变量ch。 • cin.get(字符数组buf, 字符个数n, 结束符delim) • 用于从指定的输入流中读取n-1个字符,并将这些字符赋给字符数组buf。如果还没有读取完n-1个字符之前就遇到结束符delim,则可提前结束读取过程。结束符delim的默认值为换行符‘\n’ 。

  9. 例8-2:包含空格的字符串的输入与输出 #include <iostream> using namespace std; int main() { char ch1, ch2, ch3, buf1[50], buf2[50]; cout << "请输入一个句子:"; cin >> 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; }

  10. 输入流对象的成员函数 • 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 the stream. • gcount • Counts the characters extracted in the last unformatted operation.

  11. 8.3 标准输出流 • 输出流类ostream的标准输出流对象cout通过流插入运算符“<<”,把变量的值从内存输出到标准输出设备上。 • 系统会自动根据不同的数据类型采用不同的默认方式输出。 • 特殊要求的输出格式,需要格式化I/O • 使用流操纵符对输出操作进行格式化 • 使用ios类的格式控制成员函数进行格式化

  12. 1. 使用流操纵符对输出操作进行格式化 • 不带参数的流操纵符 • endl • dec/oct/hex 十/八/十六进制 • 带参数的流操纵符 (注意:需包含头文件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 指定整数应作为十六进制(基数16)值 • ios::showpos 指定正数和负数前面分别加上+和-号 • ios::fixed 指定浮点数以小数方式输出 • ios::scientific 指定浮点数输出采用科学记数法

  13. 例8-4:改变整数的进制 #include <iostream> 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; }

  14. 例8-3:设置实型数的精度 #include <iostream> #include <iomanip> #include <cmath> 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) << setiosflags( ios::scientific) ; cout << "以科学记数方式,采用不同精度输出:" << endl; for ( i = 0; i <= 4; i++ ) cout << setprecision( i ) << "r = " << r << endl; return 0; }

  15. 例8-5:设置输出宽度、填充字符和对齐方式 #include <iostream> #include <iomanip> using namespace std; int main() { double pi=3.14159; // 以默认方式输出 cout << pi << endl; // 设置输出宽度后进行输出 cout << setw(10) << pi << endl; // 使用填充字符并设置输出宽度后进行输出 cout << setfill('*') << 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; }

  16. 2. 使用ios类的格式控制成员函数对输出操作进行格式化 • 格式化函数 • width(w) 设置显示字段宽度为w • precision(p) 设置浮点数精度为p • fill(ch) 设置填充字符为ch • setf(flags) 设置输出格式状态为flags • unsetf(flags) 清除格式标记flags • 其中,流格式状态标志字(flags)同前。

  17. #include <iostream> 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.12345<<endl; cout.setf(ios::uppercase | ios::scientific); cout<< 10.12345<<endl; cout.unsetf(ios::uppercase); cout << 10.12345<<endl; return 0; } 运行结果: 10.12 *****10.12 *******Hi! 10.12***** 1.0123E+001 1.0123e+001

  18. 规 则 • 成员函数width(w)和流操纵符setw(w)都只对其后的第一个输出项有效 • 用成员函数setf或流操纵符setiosflags设置输出格式后,如果要改为同组另一状态,应调用unsetf或resetiosflags先终止 • ios::left • ios::right

  19. 输出流对象的成员函数 • 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 stream’s put pointer. • tellp • Gets the value of the stream’s put pointer.

  20. 8.4 文件 • 8.4.1 文件和流 • 8.4.2文件的打开和关闭 • 8.4.3文件的读写

  21. ios istream ostream ifstream iostream ofstream fstream 8.4.1 文件和流 • C++把每一个文件都看成一个有序的字节流,对文件的操作可采用与输入输出流相关的方法。 • 头文件fstream包含了流类ifstream(从文件输入)、ofstream(向文件输出)和fstream(从文件输入/输出)的定义。 文件I/O流类的继承层次结构 #include <fstream>

  22. 8.4.2 文件的打开和关闭 • 文件的处理由三个步骤组成:打开文件,数据读写,关闭文件。 • 1. 打开文件,两种方法: • 1)先建立文件流对象,再调用成员函数open()将它与某一个文件关联 ifstream infile; // 输入文件流对象 ofstream outfile; // 输出文件流对象 fstream iofile; // 输入输出文件流对象 outfile.open("a.dat"); • 2)在建立文件流对象的同时通过构造函数来打开文件。如: ofstream outfile ("a.dat"); • 测试文件是否被正确打开的方法如下: if ( ! outfile) { … // 处理文件打开失败情况的代码 } • 2. 关闭文件:成员函数close() outfile.close( );

  23. 8.4.3 文件的读写 • 使用插入与提取运算符对文件进行读写 • >>读文件 • 写文件 << • 使用类成员函数对文件流进行操作 • get读/put写 一次读写一个字节 • istream& get ( char& rch); • ostream& put ( char ch); • getline 一次读一行 • istream& getline(char* pch, int nCount, char delim = '\n' );

  24. // 例8-6:写文件 #include <iostream> #include <fstream> 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; }

  25. // 例8-7:读文件 #include <iostream> #include <fstream> using namespace std; int main() { ifstream infile("grade.txt"); if(!infile) { cout << "文件打开失败!"<<endl; return 1; } char course[20]; float score; infile >> course >> score; cout << course << " " << score << endl; infile >> course >> score; cout << course << " " << score << endl; infile >> course >> score; cout << course << " " << score << endl; infile >> course >> score; cout << course << " " << score << endl; infile.close(); return 0; } 注意:VC++ 6.0编译器不能正确判断if(! infile)

  26. // 例8-8:使用成员函数get()完成文件读操作 #include <iostream> #include <fstream> using namespace std; int main() { char ch; int count=0; // 计数器 ifstream infile("grade.txt"); if(!infile) { cout << "文件打开失败"<<endl; return 1; } while(!infile.eof( )) { infile.get(ch); // 从文件流中读入下一个字符 cout<<ch; // 屏幕输出从文件中读入的字符 if(ch>='0' && ch<='9') count++; // 若是数字字符,计数器加1 } cout<<endl<<"文件中共有数字字符:"<<count<<"个。"<<endl; infile.close(); return 0; }

  27. 扩展阅读 • 8.5 二进制文件 • 二进制文件以位(bit)为单位,整个文件是由0和1组成的无格式的原始数据序列。在二进制方式下的输入输出过程中,系统不对数据进行任何转换。 • 文本文件以字节(byte)为单位,整个文件实际保存的是一串ASCII字符。可用文字处理器进行编辑。在文本方式下的输入输出过程中,系统进行字符转换。

  28. openmode 说 明 ios::app 将所有输出写入文件末尾 ios::ate 打开文件以便输出,并移到文件末尾(通常用于添加数据) 数据可以写入文件中的任何地方 ios::in 打开文件以便输入 ios::out 打开文件以便输出 ios::trunc 删除文件现有内容(是ios::out的默认操作) ios::binary 用二进制而不是文本模式打开文件 ios::nocreate 如果文件不存在,则文件打开失败 ios::noreplace 如果文件存在,则文件打开失败 文件打开方式

  29. // 例8-9:文件拷贝的程序 #include <iostream> #include <fstream> using namespace std; int main() { char s[50], d[50]; cout<<"请输入准备复制的文件名(含后缀名):"; cin>>s; cout<<"请输入新生成的文件名(含后缀名):"; cin>>d; 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( )用于从输入流中读取一个字符到变量ch outfile.put(ch); // 成员函数put( )将字符变量ch中的字符写到输出流中 } infile.close(); outfile.close(); return 0; }

  30. 上机指导 • 8.5 Visual C++的帮助功能

  31. 应用举例 • 例8-10 打开一个由若干个整数组成的文本文件“number.txt”,找出其中所有的质数并存入另一个文本文件“prime.txt”中。 • 例8-11 编写程序,可以读入一个C/C++语言的源文件,并在每一行前面加上行号后保存到另一个名为print.txt的文件中。

  32. // 例8-10:文件操作 #include <iostream> #include <fstream> using namespace std; int isprime(int a) // 素数判别函数 { for(int i=2; i<=a/2; i++) if(a%i == 0) return 0; return 1; } int main() { ifstream infile("number.txt"); ofstream outfile("prime.txt"); if(!infile || !outfile) { cout << "文件打开失败!"<<endl; return 1; } int num; while(!infile.eof() ) { infile>>num; if(isprime(num)) outfile<<num<<" "; } infile.close(); outfile.close(); return 0; }

  33. // 例8-11:源文件加行号 #include <iostream> #include <iomanip> #include <fstream> 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; }

  34. 结 束 语 学好程序设计语言的唯一途径是 你的编程能力与你在计算机上投入的时间成 上机练习 正比

More Related