1 / 60

补充内容 : C++ 的 I/O 流库

补充内容 : C++ 的 I/O 流库. 输入 / 输出 (I/O) 是每个程序的基本功能。 输入:是指将数据从外部设备传送到计算机内存的过程; 输出:是指将运算结果从计算机内存传送到外部输出设备的过程。 流的概念: C++ 将数据从一个对象到另一个对象的流动抽象为“流”,流动的方向不同,构成了输入 / 输出流,即 I/O 流。. 主要内容. 流抽象的继承结构 预定义的插入符与提取符 插入符和提取符的重载 磁盘文件的输入和输出 字符串流. 流抽象的继承结构. 1 、流的基本概念.

Download Presentation

补充内容 : C++ 的 I/O 流库

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. 补充内容:C++的I/O流库 • 输入/输出(I/O)是每个程序的基本功能。 • 输入:是指将数据从外部设备传送到计算机内存的过程; • 输出:是指将运算结果从计算机内存传送到外部输出设备的过程。 • 流的概念:C++将数据从一个对象到另一个对象的流动抽象为“流”,流动的方向不同,构成了输入/输出流,即I/O流。

  2. 主要内容 • 流抽象的继承结构 • 预定义的插入符与提取符 • 插入符和提取符的重载 • 磁盘文件的输入和输出 • 字符串流

  3. 流抽象的继承结构 1、流的基本概念 • 在C++中,语言本身并不包含输入和输出功能,但C++标准库提供了一套用于输入和输出的类库。 • 在C++的输入、输出系统中,最核心的对象是流(stream),一个流就是一个字节序列。流的操作包括对流的读和写。 • C++输入输出流的思想:令标准I/O、文件和存储块看上去都一样,只需记住一个接口就可以了。与标准C输入输出库的各种函数相比,输入输出流更容易、更安全、更有效。

  4. 流抽象的继承结构(续)

  5. ios streambuf istream ostream iostream 流抽象的继承结构(续) 2、C++流的继承结构 • ios:对流状态进行设置,虚基类; • streambuf:提供对数据的缓冲支持; • istream、ostream、iostream:提取与插入;

  6. fstreambase filebuf ifstream ofstream iofstream 流抽象的继承结构(续) 3、文件的继承结构 • fstreambase:公共基类; • filebuf:提供对上述类的缓冲支持; • ifstream、ofstream、iofstream:文件操作;

  7. 流抽象的继承结构(续) 4、字符串类 提供处理内部初始化字符序列的操作; istrstream:从序列中取字符; ostrstream:将字符放入序列;

  8. 流抽象的继承结构(续) 5、预定义的流 • cin:istream类对象,处理标准输入,即键盘输入; • cout:ostream类对象,处理标准输出,即屏幕输出; • cerr:ostream类对象,处理标准出错信息,提供不带缓冲区的输出; • clog:ostream类对象,处理标准出错信息,提供带缓冲区的输出;

  9. 预定义的插入符 1、预定义插入符的格式 ostream& ostream::operator <<(const type& obj); 其中:type为char、int、short、long类型和它们的unsigned和signed类型,以及float、double、long double、char *和void *; 2、说明 • 一般情况下将插入符作用于cout对象; • 输出语句中可以串联多个插入运算符,输出多个数据项;

  10. 预定义的插入符(续) • 插入运算符后可以是任意复杂的表达式,系统可自动计算其值并传给插入符; • 指针类型的地址值,默认为十六进制显示,用类型long强制后才可以十进制显示; • 字符指针的地址值的输出格式为:(void *)s或void *(s),此时仍为十六进制格式;

  11. 地址值的 十进制 表示方法 地址值的 十六进制 表示方法 字符指 针地址 预定义的插入符(续) #include <iostream.h> #include <string.h> void main() { char *str="Hello"; int a=100; int *pa=&a; cout<<"*pa="<<*pa<<endl; cout<<"&pa="<<&pa<<" or "<<long(&pa)<<endl; cout<<"The string is "<<str<<endl; cout<<"The address is "<<(void *)str <<" or "<<long((void *)str)<<endl; } 例1:分析下列程序的输出结果。 //字符指针

  12. 预定义的插入符(续)   *pa=100 &pa=0x0065FDEC or 6684144 The string is Hello The address is 0x00426064 or 4350052 输出

  13. 控制输出格式 • 控制输出宽度 • 为了调整输出,可以通过在流中放入setw操纵符或调用width成员函数为每个项指定输出宽度。 • 例:使用width控制输出宽度 #include <iostream.H> int main() { double values[] = {1.23,35.36,653.7,4358.24}; for(int i=0;i<4;i++) { cout.width(10); cout << values[i] <<'\n'; } } 输出结果: 1.23 35.36 653.7 4358.24

  14. 例:使用*填充 #include <iostream.h> int main() { double values[]={1.23,35.36,653.7,4358.24}; for(int i=0; i<4; i++) { cout.width(10); cout.fill('*'); cout<<values[i]<<'\n'; } } 输出结果: ******1.23 *****35.36 *****653.7 ***4358.24

  15. 例: 使用setw指定宽度 #include <iostream.h> #include <iomanip.h> int main() { double values[]={1.23,35.36,653.7,4358.24}; char *names[]={"Zoot","Jimmy","Al","Stan"}; for(int i=0;i<4;i++) cout<<setw(6)<<names[i] <<setw(10)<<values[i] <<endl; } 输出结果: Zoot 1.23 Jimmy 35.36 Al 653.7 Stan 4358.24

  16. 例:设置对齐方式 #include <iostream.h> #include <iomanip.h> int main() { double values[]={1.23,35.36,653.7,4358.24}; char *names[]={"Zoot","Jimmy","Al","Stan"}; for(int i=0;i<4;i++) cout<<setiosflags(ios::left) <<setw(6)<<names[i] <<resetiosflags(ios::left) <<setw(10)<<values[i] <<endl; } 输出结果: Zoot 1.23 Jimmy 35.36 Al 653.7 Stan 4358.24

  17. 例:控制输出精度 #include <iostream.h> #include <iomanip.h> int main() { double values[]={1.23,35.36,653.7,4358.24}; char *names[]={"Zoot","Jimmy","Al","Stan"}; cout<<setiosflags(ios::scientific); for(int i=0;i<4;i++) cout<<setiosflags(ios::left) <<setw(6)<<names[i] <<resetiosflags(ios::left) <<setw(10)<<setprecision(1) << values[i]<<endl; } 输出结果: Zoot 1.2e+000 Jimmy 3.5e+001 Al 6.5e+002 Stan 4.4e+003

  18. 预定义的插入符(续) 3、使用put()输出一个字符 ostream& ostream::put(char c); 4、使用write()输出多个字符 ostream& ostream::write(char *buf,int n); 说明: 这些成员函数既可用于文本流,也可用于二进制流,尤其适用于二进制流;

  19. 预定义的插入符(续) #include <iostream.h> void main() { cout<<'a'<<', '<<'b'<<'\n'; cout.put('a').put(', ').put('b').put('\n'); char c1='A',c2='B'; cout.put(c1).put(c2).put('\n'); } 例2:分析下列程序的输出结果。 a,b a,b AB 输 出

  20. 预定义的插入符(续) #include <iostream.h> #include <string.h> void PrintString(char *s) { cout.write(s,strlen(s)).put('\n'); cout.write(s,6)<<"\n"; } void main() { char str[]="I love C++"; cout<<"The string is: "<<str<<endl; PrintString(str); PrintString("this is a string"); } 例3:分析下列程序的输出结果。

  21. 预定义的插入符(续) The string is: I love C++ I love C++ I love this is a string this i 输出

  22. 预定义的提取符 1、预定义提取符的格式 istream& istream::operator >>(type& obj); 其中:type为char、int、short、long类型和它们的unsigned和signed类型,以及float、double、long double、char *; 2、说明 • 一般情况下将提取符作用于cin对象; • 输入语句中可以串联多个提取运算符,每个提取符后为一表达式,该表达式是获得输入值的变量或对象;

  23. 预定义的提取符(续) • 提取操作时,空白符(空格、tab键、换行符)只用于字符的分隔符,而本身不作为从输入流中提取的字符; • 提取符可从输入流中读取一个字符串,该字符串是以空白符结束的一个字符序列,由系统自动加上'\0'字符;

  24. 预定义的提取符(续) while(cin>>buf) { curLen=strlen(buf); cnt++; if(curLen>maxLen) { maxLen=curLen; largest=buf; } } cout<<endl; cout<<cnt<<endl; cout<<maxLen<<endll; cout<<largest<<endl; } #include <iostream.h> #include <string.h> void main() { const int SIZE=20; char buf[SIZE]; char *largest; int curLen; int maxLen=-1; int cnt=0; cout<<"Input words:"<<endl; 例4:分析下列程序的输出结果。

  25. 预定义的提取符(续) Input words: if else return do while continue<ctrl+z> 输 入 6 8 continue 输 出 输入ctrl+z键后,cin>>buf 的值为0,退出while循环;

  26. 预定义的提取符(续) 3、使用get()获取一个字符 istream& istream::get(char& c); char istream::get(); 4、使用getline()获取多个字符 istream& istream::getline (char *buf,int Limit,char deline='\n'); 说明: • getline()最多可读取Limit-1个字符;

  27. 预定义的提取符(续) • getline()函数结束操作的条件: 从输入流中读取Limit-1个字符后; 从输入流中读取换行符或其他终止符后; 从输出流中读取到文件或输入流结束符后; • getline()通常用来读取一行字符 5、使用read()读取一串字符 istream& istream::read(char *,int);

  28. 预定义的提取符(续) #include <iostream.h> void main() { char ch; cout<<"Input: "; while((ch=cin.get())!=EOF) cout.put(ch); cout<<"OK! "<<endl; } 例5:分析下列程序的输出结果。 abc xyz 123<Enter> <ctrl+z> 输入 输出 abc xyz 123<Enter>

  29. 预定义的提取符(续) #include <iostream.h> void main() { const int S=12; char buf[S]=""; cout<<"Input…"<<endl; cin.read(buf,S); cout<<endl; cout<<buf<<endl; } 例6:分析下列程序的输出结果。 输入: Input... abcd<Enter> efgh<Enter> ijkl<Enter> Input… abcd efgh ijkl 输 出

  30. 插入符和提取符的重载 1、重载为友元函数 ostream& operator<<(ostream&s,const type& p); istream& operator>>(istream&s,type& p); 2、函数调用形式 ostrm<<obj; 等价于    operator <<(ostrm,obj); ostrm<<obj1<<obj2; 等价于 operator <<(operator<<(ostrm,obj1),obj2); istrm>>obj; 等价于    operator >>(istrm,obj); istrm>>obj1>>obj2; 等价于 operator >>(operator>>(istrm,obj1),obj2);

  31. 插入符和提取符的重载(续) #include <iostream.h> class Date { public: Date(int y,int m,int d) { Year=y; Month=m; Day=d; } friend ostream& operator << (ostream& stream,Date& date); friend istream& operator >> (istream& stream,Date& date); 例7:分析下列程序的输出结果。

  32. 插入符和提取符的重载(续) private: int Year,Month,Day; }; ostream& operator <<(ostream& stream,Date& date) { stream<<date.Year<<"/"<<date.Month<<"/" <<date.Day<<endl; return stream; } istream& operator >>(istream& stream,Date& date) { stream>>date.Year>>date.Month>>date.Day; return stream; } void main()

  33. 插入符和提取符的重载(续) { Date CDate(1999,10,22); cout<<"Current date: "<<CDate<<endl; cout<<"Enter new date: "; cin>>CDate; cout<<"New date: "<<CDate<<endl; } Current date: 1999/10/22 Enter new date: 2001 10 22 New date: 2001/10/22 输 出

  34. 磁盘文件的打开和关闭 1、打开文件 • void fstream::open(const char *fname, int mode,int= filebuf::openprot); • fstream::fstream(const char *fname, int mode,int= filebuf::openprot); • void ofstream::open(const char *fname, int mode=ios::out,int= filebuf::openprot); • ofstream::ofstream(const char *fname, int mode=ios::out,int= filebuf::openprot); • void ifstream::open(const char *fname, int mode=ios::in,int= filebuf::openprot); • ifstream::ifstream(const char *fname, int mode=ios::in,int= filebuf::openprot);

  35. 磁盘文件的打开和关闭(续) 说明: 第一个参数是指向要打开的文件名字串,第二个和第三个参数说明文件如何被打开。 参数mode:打开方式 ios::ate —— 如果文件存在,输出内容加在末尾 ios::in —— 具有输入能力(ifstream默认) ios::out —— 具有输出能力(ofstream默认) ios::trunc —— 如文件存在,清除文件内容(默认) ios::nocreate —— 如文件不存在,返回错误 ios::noreplace —— 如文件存在,返回错误 ios::binary —— 以二进制方式打开文件

  36. 磁盘文件的打开和关闭(续) 参数prot:文件保护方式 filebuf::openprot ——兼容共享方式 filebuf::sh_none ——独占,不共享 filebuf::sh_read ——允许读共享 filebuf::sh_write ——允许写共享

  37. 磁盘文件的打开和关闭(续) 2、关闭文件 void fstream::close(); void ofstream::close(); void ifstream::close();

  38. 磁盘文件的打开和关闭(续) #include <fstream.h> void main() { ofstream ostrm; ostrm.open("f1.dat"); ostrm<<120<<endl; ostrm<<310.85<<endl; ostrm.close(); ifstream istrm("f1.dat"); int n; double d; istrm>>n>>d; cout<<n<<", "<<d<<endl; istrm.close(); } 例8:分析下列程序的输出结果。 输出: 120,310.85

  39. 文本文件的读写操作 #include <iostream.h> #include <fstream.h> #include <stdlib.h> void main() { fstream outfile; outfile.open("f2.dat",ios::out); if(!outfile) { cout<<"f2.dat can't open. "<<endl; abort(); } outfile<<"this is a program. "<<endl; outfile.close(); } 例9:将文本写入指定的文件。 退出程序

  40. 文本文件的读写操作(续) #include <iostream.h> #include <fstream.h> #include <stdlib.h> void main() { fstream infile; infile.open("f2.dat",ios::in); if(!infile) { cout<<"f2.dat can't open. "<<endl; abort(); } char s[80]; while(!infile.eof()) { infile.getline(s,sizeof(s)); cout<<s<<endl; } infile.close(); } 例10:从文本文件中读出信息。

  41. 文本文件的读写操作(续) #include <iostream.h> #include <fstream.h> #include <stdlib.h> #include <string.h> void main() { fstream outfile,infile; outfile.open("f3.dat",ios::out); if(!outfile) { cout<<"f3.dat can't open. "<<endl; abort(); } char str[]="this is a c++ program. "; 例11:使用get()和put()函数读写文件。

  42. 文本文件的读写操作(续) for(int i=0;i<strlen(str);i++) outfile.put(str[i]); outfile.close(); infile.open("f3.dat",ios::in); if(!infile) { cout<<"f3.dat can't open. "<<endl; abort(); } char ch; while(infile.get(ch)) cout<<ch; cout<<endl; infile.close(); } 输出: this is a c++ program.

  43. 文本文件的读写操作(续) #include <iostream.h> #include <fstream.h> #include <stdlib.h> void main() { fstream outfile,infile; infile.open("f2.dat",ios::in); if(!infile) { cout<<"f2.dat can't open. "<<endl; abort(); } outfile.open("f4.dat",ios::out); if(!outfile) 例12:将一文件内容拷贝到另一文件。

  44. 文本文件的读写操作(续) { cout<<"f4.dat can't open. "<<endl; abort(); } char ch; while(infile.get(ch)) outfile.put(ch); infile.close(); outfile.close(); }

  45. 二进制文件的读写操作 #include <iostream.h> #include <fstream.h> #include <stdlib.h> struct person { char name[20]; double height; int age; } struct person people[4]={"Wang",1.65,25, "Zhang", 1.72,24, "Li",1.89,21, "Huang",1.70,22}; void main() { fstream outfile,infile; 例13:对一二进制文件进行读写操作。

  46. 二进制文件的读写操作(续) outfile.open("f5.dat",ios::out|ios::binary); if(!outfile) { cout<<"f5.dat can't open. "<<endl; abort(); } for(int i=0;i<4;i++) outfile.write((char *)&people[i], sizeof(people[i])); outfile.close(); infile.open("f5.dat",ios::in|ios::binary); if(!infile) { cout<<"f5.dat can't open. "<<endl; abort();

  47. 二进制文件的读写操作(续) } for(int i=0;i<4;i++) { outfile.read((char *)&people[i], sizeof(people[i])); cout<<people[i].name<<"\t" <<people[i].height<<"\t" <<people[i].age<<endl; } infile.close(); } Wang 1.65 25 Zhang 1.72 24 Li 1.69 21 Huang 1.7 22 输 出

  48. 随机访问数据文件 1、读文件指针 istream& istream::seekg(streampos); istream& istream::seekg(streamoff,ios::seek_dir); streampos istream::tellg(); streampos为long型; Streamoff为移动的字节数,正数表示正向,负数是反向。 seek_dir的值: cur=1,相对于当前读指针指定的位置; beg=0,相对于流的开始位置; end=2,相对于流的结尾位置;

  49. 随机访问数据文件(续) 2、写文件指针 ostream& ostream::seekp(streampos); ostream& ostream::seekp(streamoff,ios::seek_dir); streampos ostream::tellp();

  50. 随机访问数据文件(续) #include <iostream.h> #include <fstream.h> #include <stdlib.h> void main() { struct student { char name[20]; long number; double totalscore; }struct stu[5]={"Ma",97001,85.72, "Li",97002,92.62, "Hu",97003,89.25, "Yan",97004,90.84, "Lu",97005,80.92}; 例14:分析下列程序的输出结果。

More Related