Presentation is loading. Please wait.

Presentation is loading. Please wait.

第14章 标准库和输入输出流 14.1 标准库概述 14.2 流 14.3 输入输出流 14.4 格式化I/O 14.5 文件处理

Similar presentations


Presentation on theme: "第14章 标准库和输入输出流 14.1 标准库概述 14.2 流 14.3 输入输出流 14.4 格式化I/O 14.5 文件处理"— Presentation transcript:

1 国家级精品课程网站 (本书配套教学网站) http://programming.xjtu.edu.cn

2 第14章 标准库和输入输出流 14.1 标准库概述 14.2 流 14.3 输入输出流 14.4 格式化I/O 14.5 文件处理
14.6 对象的输入/输出

3 14.1 标准库概述 一、标准库概念 用C++语言编写的类和函数库 由编译器厂商提供,与平台、厂商和编译器版本无关

4 二、标准库构成 1、标准函数库 2、标准类库 从C语言中继承下来
标准C++的I/O流类、字符串类、数字类、异常处理和杂项类以及STL容器类

5 三、标准库的使用 1、包含相应的头文件 2、C++的头文件来源: 标准C语言库函数的头文件,带有.h后缀;
由标准C语言库函数头文件变成的标准C++的头文件,把原有标准C语言库函数头文件去掉.h后缀而加上c前缀。

6 14.2 流 1、在C++中,输入输出通过流来完成 2、流类 输出操作将一个对象的状态转换成字符序列,输出到某个地方。
输入操作从某个地方接收到一个字符序列,然后将其转换成一个对象的状态所要求的格式。 接收输出数据的地方叫做目标 输入数据来自的地方叫做源 输入和输出操作看成字符序列在源、目标以及对象之间的流动。 2、流类 C++将与输入和输出有关的操作定义为一个类体系,放在一个系统库里,以备用户调用。这个执行输入和输出操作的类体系就叫做流类,提供这个流类实现的系统库就叫做流类库

7 输入/输出流类的继承层次结构 iostream流类库的层次结构

8 14.3 输入输出流 头文件iostream中含有4个对象: 格式化I/O :包含头文件iomanip
cin:标准输入流 cout :标准输出流 cerr :非缓冲标准错误流 clog :经缓冲标准错误流 格式化I/O :包含头文件iomanip 文件处理操作 :包含头文件fstream

9 输入输出流的成员函数 屏幕输出(写操作) 1. 使用预定义的插入符(<<) 2. 使用成员函数put( )写一个字符。
1. 使用预定义的插入符(<<) 2. 使用成员函数put( )写一个字符。 3. 使用成员函数write( )写一个字符串。

10 键盘输入(读操作) 1. 使用预定义的提取符(>>)。 2. 使用成员函数get( )读一个字符。
1. 使用预定义的提取符(>>)。 2. 使用成员函数get( )读一个字符。 3. 使用成员函数getline( )读一行字符。 4. 使用成员函数read( )读若干个字符。

11 输入输出流的成员函数 get():可读取输入的空格; getline():读取一行信息到字符数组中; put():输出一个字符;
ignore():跳过制定数量的字符; putback() peek() :返回输入流中的下一个字符,但不将其从输入流中删除; read()/write():无格式输入、输出; gcount():统计输入个数;

12 例14-1 比较cin和cin.get的输入 #include <iostream> using namespace std;
int main() { const int SIZE = 80; char ch1,ch2,ch3,buffer1[SIZE],buffer2[SIZE]; cout << "Enter a sentence:\n"; cin >> buffer1; cout << "The string read with cin is:\n" << buffer1; ch1 = cin.get(); ch2 = cin.get();

13 cout << "\nThe result of cin
cout << "\nThe result of cin.get() is:\n" << ch1 << ch2; cin.get(ch3); cout << "\nThe result of cin.get(ch3) is:\n" << ch3; cin.get(buffer2,SIZE); cout << "\nThe string read with cin.get(buffer2,SIZE) is:\n" << buffer2 << endl; return 0; }

14 14.4 格式化I/O 1. 使用状态标志和成员函数进行格式化输出 (1) 控制格式的标志位。 定义标志位的组合(静态变量):
1. 使用状态标志和成员函数进行格式化输出 (1) 控制格式的标志位。 定义标志位的组合(静态变量): basefield del|oct|hex adjustfield left|right|internal floatfield seientific|fixed

15 例:cout.flags(ios::scientific|ios::showpos);
(2) 设置标志字的成员函数 long flags( ):返回流格式标志的当前设置; 例:cout.flags(ios::scientific|ios::showpos); long setf():设置流格式标志 例:cout.setf(ios::uppercase|ios::scientific); long unsetf(long):清除流格式标志

16 (3) 控制输出格式和成员函数 设置域宽:int width( ) 填充字符:int fill( )
设置精度:int precision( )

17 例题 #include <iostream> using namespace std; int main()
{ cout.precision (4); cout.width(10); cout<< <<endl; cout.fill ('*'); cout.width (10); cout<<"Hi"<<endl; cout.setf(ios::left); return 0; }

18 二. 流操纵符 系统I/O流类库中所定义的操作符被放在iomanip.h文件中。 常量名 含 义 skipws 跳过输入中的空白
常量名 含 义 skipws 跳过输入中的空白 left 输出数据按输出域左边对齐输出 right 输出数据按输出域右边对齐输出 internal 在指定任何引导标志或基之后填充字符 dec 转换基数为十进制形式 oct 转换基数为八进制形式 hex 转换基数为十六进制形式 showbase 输出带有一个表示制式的字符 showpoint 浮点输出时必须带有一个小数点和尾部的0

19 常量名 含 义 uppercase 十六进制数值输出使用大写A~F,科学计数 显示使用大写字母E showpos 在正数前添加一个“+”号 fixed 使用定点形式表示浮点数 scientific 使用科学计数法表示浮点数 untibuf 每次插入之后, ostream∷osfx刷新该 流的缓冲区。默认缓冲单元为cerr setbase(base) 将基数设置为base

20 例14-2 设置整数流的基数 #include <iostream> #include <iomanip>
using namespace std; int main() { int n; cout << "Enter a decimal number: "; cin >> n; cout << n << " in hexadecimal is: " << hex << n << '\n' << dec << n << " in octal is: " << oct << n << '\n' << setbase( 10 ) << n << " in decimal is: " << n << endl; return 0; }

21 例14-3 设置浮点数精度 #include <iostream> #include <iomanip>
#include <cmath> using namespace std; int main() { double root2 = sqrt( 2.0 ); int places; cout << setiosflags( ios::fixed) << "Precision set by the precision member function:" << endl;

22 for ( places = 0; places <= 4; places++ )
{ cout.precision( places ); cout << root2 << '\n';} cout << "Precision set by the " << "setprecision manipulator:\n"; cout << setprecision( places ) << root2 << '\n'; return 0; }

23 14.5 文件处理 基本概念 打开和关闭文件 文件指针 缓冲区

24 一、文件和流

25 二. 打开和关闭文件 (1) 打开文件的两种方法 方法一: 或者 fstream 〈流对象名〉; 流对象名.open("文件名″,方式);

26 方法二: ① 打开写文件 或者 ofstream 〈流对象名〉; 〈流对象名〉.open(″〈文件名〉″);

27 〈流对象名〉.open(″〈文件名〉″); 或者
② 打开读文件 ifstream〈流对象名〉; 〈流对象名〉.open(″〈文件名〉″); 或者 ifstream 〈流对象名〉.open(″〈文件名〉″);

28 (2) 关闭文件方法 流对象名.close( );

29 打开方式 说明 ios∷in 打开文件进行读操作,这种方式可避免删除现存文件的内容 ios∷out 打开文件进行写操作,这是默认模式
ios∷ate 打开一个已有输入或输出文件并查找到文件尾 ios∷app 打开文件以便在文件的尾部添加数据 ios∷nocreate 如果文件不存在,则打开操作失败 ios∷noreplace 如果设置了ios ∷ ate或ios∷app,则可打开已有文件,否则不能打开 ios∷binary 指定文件以二进制方式打开,默认为文本方式 ios∷trunc 如文件存在,将其长度截断为零并清除原有内容

30 创建一个名为“grade”的文本文件,并写入3门课程的名字和成绩。
三. 文件的读写 创建一个名为“grade”的文本文件,并写入3门课程的名字和成绩。 #include <iostream> #include <fstream> using namespace std;

31 int main() { ofstream out("grade"); if(!out) { cout << "Cannot open the grade file." << endl; return 1; } out << "C++" << " " <<89.5 << endl; out << "English" << " " << 93.5 << endl; out << "Maths" << " " << 87 << endl; out.close(); return 0;

32 例14-5 读文件 int main() { ifstream in("grade"); if(!in){
cout << "Cannot open grade file.\n"; return 1; }

33 char course[20]; float grade;
in >> course >> grade; cout << course << " " << grade << "\n"; in >> course >> grade; in.close(); return 0; }

34 四. 二进制文件 下面以将内存中存放数组a的内容写入data.dat文件为例。a占20个字节,用len表示。
四. 二进制文件 下面以将内存中存放数组a的内容写入data.dat文件为例。a占20个字节,用len表示。 ① 使用ofstream构造函数中的模式参量指定二进制输出模式: ofstream wf(″data.dat″,ios∷binary); wf.write((char *)a, len);

35 wf.open(″data.dat″,ios∷binary); wf.write((char *)a, sizeof a);
② 使用ofstream构造一个输出流,然后使用open函数指定写入方式: ofstream wf; wf.open(″data.dat″,ios∷binary); wf.write((char *)a, sizeof a);

36 ③ 构造一个流之后,再使用setmode成员函数改变模式:
ofstream wf(″data.dat″); wf.setmode(filebuf∷binary); wf.write((char *)a, len);

37 ④ 使用二进制操作符代替setmode成员函数:
ofstream wf(″data.dat″); wf<<binary; wf.write((char *)a, len);

38 例14-6 文件显示 #include <iostream> #include <fstream>
例14-6 文件显示 #include <iostream> #include <fstream> using namespace std; int main(int argc, char *argv[]) { char ch; if(argc!=2) { cout << "Usage: ProgramName <filename>\n"; return 1;} ifstream in(argv[1], ios::in | ios::binary);

39 if(!in) { cout << "Cannot open the file."; return 1;} while(in) { // in will be false when eof is reached in.get(ch); if(in) cout << ch; } return 0;

40 例 14-7 读写二进制的形式文件 将3门课程的名字和成绩以二进制的形式存放在磁盘中,然后读出该文件,并将内容显示在屏幕上。
例 读写二进制的形式文件 将3门课程的名字和成绩以二进制的形式存放在磁盘中,然后读出该文件,并将内容显示在屏幕上。 #include <iostream> #include <fstream> using namespace std; struct list { char course[10]; int score; };

41 int main() { list st1[3], st2[3]; int i; ofstream out("grade", ios::binary); if(!out) { cout << "Cannot open the grade file.\n"; return 1; }

42 for (i=0; i<3; i++) { cin >> st1[i].course >> st1[i].score; out.write((char *)&st1[i], sizeof(st1[i]));} out.close(); ifstream in("grade", ios::binary); if(!in) { cout << "Cannot open the grade file.\n"; return 1; }

43 cout << "File grade:" << endl;
for (i=0; i<3; i++) { in.read((char *)&st2[i], sizeof(st2[i])); cout << st2[i].course << " " << st2[i].score << endl;} in.close(); return 0; }

44 五、随机文件操作 随机访问文件。使用I/O流类库中提供的定位读指针和定位写指针的成员函数。

45 (1) 定位读指针的成员函数 istream & istream ∷seekg(流中位置);
long istream ∷tellg( ); 其中,〈流中位置〉和〈偏移量〉都是long型量,用字节数表示。〈参照位置〉有如下几种: cur=1相对于当前指针位置 beg=0相对于流的开始位置 end=2相对于流的结尾位置

46 (2) 定位写指针的成员函数 ostream & ostream ∷seekp(流中位置);
long ostream ∷tellp( );

47 例 模拟电视频道的存储 模拟电视频道的存储和选择。创建一个文件,通过键盘输入电视频道序号和名称,并写入文件;文件中的内容可以输出到屏幕上。 #include <iostream> #include <fstream> #include <iomanip> #include <cstdlib> using namespace std; struct TVChannel { int channelNum; char channelName[20]; }; void outputLine( ostream &output, const TVChannel &c );

48 int main() { ofstream outTV( "tv.dat", ios::ate | ios::binary); if ( !outTV ) { cerr << "File could not be opened." << endl; return 1; } cout << "Enter channel number " << "(1 to 100, 0 to end input)\n? "; TVChannel tv; cin >> tv.channelNum;

49 while ( tv.channelNum > 0 && tv.channelNum <= 100 ) {
cout << "Enter Channel Name\n? "; cin >> tv.channelName; outTV.seekp( ( tv.channelNum - 1 ) * sizeof( TVChannel ) ); outTV.write( (char *)( &tv ), sizeof( TVChannel ) ); cout << "Enter channel number\n? "; cin >> tv.channelNum; }

50 outTV.close(); ifstream inTV( "tv.dat", ios::in ); if ( !inTV ) { cerr << "File could not be opened." << endl; return 1; }

51 cout << setiosflags( ios::left ) << setw( 10 ) << "ChannelNum"
<< setw( 20 ) << "Channel Name" << endl; inTV.read( (char *)( &tv ), sizeof( TVChannel ) ); while ( inTV&& !inTV.eof() ) { if ( tv.channelNum != 0 ) outputLine( cout, tv ); inTV.read( (char *)( &tv ), sizeof( TVChannel ) ); } return 0;

52 void outputLine( ostream &output, const TVChannel &tv )
{ output << setiosflags( ios::left ) << setw( 10 ) << tv.channelNum << setw( 20 ) << tv.channelName << '\n'; }

53 程序设计举例 修改第12章实例编程的Date类,重载<<运算符,输出Date对象。 class Date { friend ostream &operator<<( ostream &, const Date & ); int day, month, year; 在Date.cpp文件中添加如下代码: ostream &operator<<( ostream &output, const Date &d ) { static char *monthName[ 12 ] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; output << monthName[ d.month-1 ] << ' ' << d.day << ", " << d.year; return output; }

54 // Example14-9.cpp演示完整的日期类
#include <iostream > #include "date.h" using namespace std; int main() { Date today, Olympicday(2004,8,13); cout << "Today (the computer's day) is: " << today<< endl; today += 365; cout << "After 365 days, the date is: " << today << endl; Date testday(2,28);

55 cout << "the test date is: " << testday << endl;
Date nextday = testday + 1; cout << "the next date is: " << testday << endl; today.SystemDate(); cout << "the Athens Olympic Games openday is: " << Olympicday << endl; cout << "And after " << Olympicday-today << " days, the Athens Olympic Games will open." <<endl; return 0; }

56 例14-10 名字空间的使用。 // Example 14-10:名字空间的使用 #include <iostream>
namespace university { int grade=4; } namespace highschool { int grade=3;

57 int main() { std::cout<<"The university's grade is: "<<university::grade <<std::endl; std::cout<<"The highschool's grade is: "<<highschool::grade <<std::endl; return 0; }

58 例14-11 改写例14-6的程序 分别以十六进制的形式和ASCII码的形式显示文件的内容。
例 改写例14-6的程序 分别以十六进制的形式和ASCII码的形式显示文件的内容。 #include <iostream> #include <fstream> #include <cctype> #include <iomanip> using namespace std; int main(int argc, char *argv[]) { if(argc!=2) { cout << "Usage: ProgramName <filename>\n"; return 1; }

59 ifstream in(argv[1], ios::in | ios::binary);
if(!in) { cout << "Cannot open input file.\n"; return 1; }

60 int i, j; int count = 0; char c[16]; cout.setf(ios::uppercase); while(!in.eof()) { for(i=0; i<16 && !in.eof(); i++) in.get(c[i]); if(i<16) i--; // get rid of eof for(j=0; j<i; j++) cout << ' ' << setw(2) << setfill('0') << hex << (int) c[j]; for(; j<16; j++) cout << " "; cout << "\t";

61 for(j=0; j<i; j++) if(isprint(c[j])) cout << c[j]; else cout << "."; cout << endl; count++;

62 if(count==16) { count = 0; cout << "Press ENTER to continue: "; cin.get(); cout << endl; } in.close(); return 0;

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


Download ppt "第14章 标准库和输入输出流 14.1 标准库概述 14.2 流 14.3 输入输出流 14.4 格式化I/O 14.5 文件处理"

Similar presentations


Ads by Google