




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C+语言程序设计(第4版)第十一章 流类库与输入/输出清华大学 郑 莉C+语言程序设计(第4版),郑莉,清华大学目录11.1 I/O流的概念及流类库结构11.2 输出流11.3 输入流11.4 输入/输出流11.5 综合实例对个人银行账户管理程序的改进11.6 深度探索11.7 小结2C+语言程序设计(第4版),郑莉,清华大学11.1 I/O流的概念及流类库结构 当程序与外界环境进行信息交换时,存在着两个对象,一个是程序中的对象,另一个是文件对象。 流是一种抽象,它负责在数据的生产者和数据的消费者之间建立联系,并管理数据的流动。 程序建立一个流对象,并指定这个流对象与某个文件对象建立连接,程序
2、操作流对象,流对象通过文件系统对所连接的文件对象产生作用。 读操作在流数据抽象中被称为(从流中)提取,写操作被称为(向流中)插入。3C+语言程序设计(第4版),郑莉,清华大学流类库结构411.1 I/O流的概念及流类库结构C+语言程序设计(第4版),郑莉,清华大学11.2 输出流 最重要的三个输出流是 ostream ofstream ostringstream5C+语言程序设计(第4版),郑莉,清华大学11.2.1 构造输出流对象 预先定义的输出流对象: cout 标准输出 cerr 标准错误输出,没有缓冲,发送给它的内容立即被输出。 clog 类似于cerr,但是有缓冲,缓冲区满时被输出。
3、611.2 输出流C+语言程序设计(第4版),郑莉,清华大学7标准输出换向ofstream fout(b.out);streambuf* pOld =cout.rdbuf(fout.rdbuf(); /cout.rdbuf(pOld); C+语言程序设计(第4版),郑莉,清华大学11.2.1 构造输出流对象(续) ofstream类支持磁盘文件输出 如果在构造函数中指定一个文件名,当构造这个文件时该文件是自动打开的 ofstream myFile(filename); 可以在调用默认构造函数之后使用open成员函数打开文件ofstream myFile; /声明一个静态文件输出流对象声明一个静
4、态文件输出流对象myFile.open(filename); /打开文件,使流对象与文件建立联系打开文件,使流对象与文件建立联系 在构造对象或用open打开文件时可以指定模式 ofstream myFile(filename, ios_base:out | ios_base:binary);811.2 输出流C+语言程序设计(第4版),郑莉,清华大学11.2.2使用插入运算符和操纵符(manipulator) 插入()运算符是所有标准C+数据类型预先设计的,用于传送字节到一个输出流对象。 插入运算符与操纵符一起工作,可以控制输出格式。很多操纵符都定义在ios_base类中(如hex()),和头
5、文件中(如setprecision())。 setw和width仅影响紧随其后的域,但其它流格式操纵符保持有效直到发生改变。 控制输出宽度 为了调整输出,可以通过在流中放入setw操纵符或调用width成员函数为每个项指定输出宽度。 dec、oct和hex操纵符设置输入和输出的默认进制。911.2 输出流C+语言程序设计(第4版),郑莉,清华大学例11-1 使用width控制输出宽度#include using namespace std; int main() double values = 1.23, 35.36, 653.7, 4358.24 ;for(int i = 0; i 4; i
6、+) cout.width(10);cout valuesi endl;return 0;1011.2 输出流 11.2.2使用插入运算符和操纵符(manipulator)输出结果输出结果: : 1.23 1.23 35.36 35.36 653.7 653.7 4358.24 4358.24C+语言程序设计(第4版),郑莉,清华大学例11-2使用setw操纵符指定宽度/11_2.cpp#include #include #include using namespace std; int main() double values = 1.23, 35.36, 653.7, 4358.24 ;s
7、tring names = Zoot, Jimmy, Al, Stan ;for (int i = 0; i 4; i+)cout setw(6) namesi setw(10) valuesi endl;return 0;1111.2 输出流 11.2.2使用插入运算符和操纵符(manipulator)输出结果输出结果: : Zoot 1.23 Zoot 1.23 Jimmy 35.36 Jimmy 35.36 Al 653.7 Al 653.7 Stan 4358.24 Stan 4358.24C+语言程序设计(第4版),郑莉,清华大学例11-3设置对齐方式/11_3.cpp#includ
8、e #include #include using namespace std; int main() double values = 1.23, 35.36, 653.7, 4358.24 ;string names = Zoot, Jimmy, Al, Stan ;for (int i=0;i4;i+)cout setiosflags(ios_base:left)/左对齐 setw(6) namesi resetiosflags(ios_base:left) setw(10) valuesi endl;return 0;1211.2 输出流 11.2.2使用插入运算符和操纵符(manipu
9、lator)输出结果:Zoot 1.23Jimmy 35.36Al 653.7Stan 4358.24C+语言程序设计(第4版),郑莉,清华大学setiosflags的参数 ios_base:skipws 在输入中跳过空白 。 ios_base:left 左对齐值,用填充字符填充右边。 ios_base:right 右对齐值,用填充字符填充左边(缺省对齐方式)。 ios_base:internal 在规定的宽度内,指定前缀符号之后,数值之前,插入指定的填充字符。 ios_base:dec 以十进制形式格式化数值(缺省进制)。 ios_base:oct 以八进制形式格式化数值 。 ios_bas
10、e:hex 以十六进制形式格式化数值。 ios_base:showbase 插入前缀符号以表明整数的数制。 ios_base:showpoint 对浮点数值显示小数点和尾部的0 。 ios_base:uppercase 对于十六进制数值显示大写字母A到F,对于科学格式显示大写字母E 。 ios_base:showpos 对于非负数显示正号(“+”)。 ios_base:scientific 以科学格式显示浮点数值。 ios_base:fixed 以定点格式显示浮点数值(没有指数部分) 。 ios_base:unitbuf 在每次插入之后转储并清除缓冲区内容。1311.2 输出流 11.2.2使
11、用插入运算符和操纵符(manipulator)C+语言程序设计(第4版),郑莉,清华大学例11-4控制输出精度/11_4.cpp#include #include #include using namespace std; int main() double values = 1.23, 35.36, 653.7, 4358.24 ;string names = Zoot, Jimmy, Al, Stan ;for (int i=0;i4;i+)cout setiosflags(ios_base:left) setw(6) namesi resetiosflags(ios_base:left)
12、/清除左对齐设置 setw(10) setprecision(1) valuesi endl;return 0;1411.2 输出流 11.2.2使用插入运算符和操纵符(manipulator)输出结果:Zoot 1Jimmy 4e+001Al 7e+002Stan 4e+003C+语言程序设计(第4版),郑莉,清华大学11.2.3文件输出流成员函数 输出流成员函数有三种类型: 与操纵符等价的成员函数。 执行非格式化写操作的成员函数。 其它修改流状态且不同于操纵符或插入运算符的成员函数。1511.2 输出流C+语言程序设计(第4版),郑莉,清华大学11.2.3文件输出流成员函数(续) open
13、函数把流与一个特定的磁盘文件关联起来。需要指定打开模式。 put函数把一个字符写到输出流中。 write函数把内存中的一块内容写到一个文件输出流中 seekp和tellp函数操作文件流的内部指针 close函数关闭与一个文件输出流关联的磁盘文件 错误处理函数在写到一个流时进行错误处理1611.2 输出流C+语言程序设计(第4版),郑莉,清华大学例11-5 向文件输出/11_5.cpp#include using namespace std;struct Date int mon, day, year; ;int main() Date dt = 6, 10, 92 ;ofstream file
14、(date.dat, ios_base:binary);file.write(reinterpret_cast(&dt),sizeof(dt);file.close();return 0;1711.2 输出流 11.2.3 文件输出流成员函数C+语言程序设计(第4版),郑莉,清华大学11.2.4 二进制输出文件 以通常方式构造一个流,然后使用setmode成员函数,在文件打开后改变模式。 使用ofstream构造函数中的模式参量指定二进制输出模式1811.2 输出流C+语言程序设计(第4版),郑莉,清华大学11.2.5 字符串输出流( ostringstream ) 用于构造字符串 功
15、能 支持ofstream类的除open、close外的所有操作 str函数可以返回当前已构造的字符串 典型应用 将数值转换为字符串1911.2 输出流C+语言程序设计(第4版),郑莉,清华大学例11-6用ostringstream将数值转换为字符串/11_6.cpp#include #include #include using namespace std; template inline string toString(const T &v) ostringstream os;/创建字符串输出流os v;/将变量v的值写入字符串流return os.str();/返回输出流生成的字符
16、串 int main() string str1 = toString(5);cout str1 endl;string str2 = toString(1.2);cout str2 endl;return 0;2011.2 输出流 11.2.5 字符串输出流( ostringstream )输出结果:51.2函数模板toString可以把各种支持“)对于所有标准C+数据类型都是预先设计好的。 是从一个输入流对象获取字节最容易的方法。 ios类中的很多操纵符都可以应用于输入流。但是只有少数几个对输入流对象具有实际影响,其中最重要的是进制操纵符dec、oct和hex。2311.3 输入流C+语言
17、程序设计(第4版),郑莉,清华大学11.3.4输入流相关函数 open函数把该流与一个特定磁盘文件相关联。 get函数的功能与提取运算符()很相像,主要的不同点是get函数在读入数据时包括空白字符。(第6章介绍过) getline的功能是从输入流中读取多个字符,并且允许指定输入终止字符,读取完成后,从读取的内容中删除终止字符。(第6章介绍过) read成员函数从一个文件读字节到一个指定的内存区域,由长度参数确定要读的字节数。如果给出长度参数,当遇到文件结束或者在文本模式文件中遇到文件结束标记字符时结束读取。2411.3 输入流C+语言程序设计(第4版),郑莉,清华大学11.3.4输入流相关函数
18、(续) seekg函数用来设置文件输入流中读取数据位置的指针。 tellg函数返回当前文件读指针的位置。 close函数关闭与一个文件输入流关联的磁盘文件。2511.3 输入流C+语言程序设计(第4版),郑莉,清华大学例11-7 get函数应用举例/11_7.cpp#include using namespace std;int main() char ch;while (ch = cin.get() != EOF)cout.put(ch);return 0;2611.3 输入流 11.3.4 输入流相关函数C+语言程序设计(第4版),郑莉,清华大学例11-8为输入流指定一个终止字符:/11_
19、8.cpp#include #include using namespace std;int main() string line; cout Type a line terminated by t endl; getline(cin, line, t); cout line endl;return 0;2711.3 输入流 11.3.4 输入流相关函数C+语言程序设计(第4版),郑莉,清华大学例11-9从一个payroll文件读一个二进制记录到一个结构中/11_9.cpp#include #include #include using namespace std;struct SalaryI
20、nfo unsigned id;double salary; int main() SalaryInfo employee1 = 600001, 8000 ;ofstream os(payroll, ios_base:out | ios_base:binary);os.write(reinterpret_cast(&employee1), sizeof(employee1);os.close();2811.3 输入流 11.3.4 输入流相关函数C+语言程序设计(第4版),郑莉,清华大学例11-9(续)ifstream is(payroll, ios_base:in | ios_bas
21、e:binary);if (is) SalaryInfo employee2;is.read(reinterpret_cast(&employee2), sizeof(employee2);cout employee2.id employee2.salary endl; else cout ERROR: Cannot open file payroll. endl;is.close();return 0;2911.3 输入流 11.3.4 输入流相关函数C+语言程序设计(第4版),郑莉,清华大学例11-10用seekg函数设置位置指针/11_10.cpp, 头部分省略int main(
22、) int values = 3, 7, 0, 5, 4 ;ofstream os(integers, ios_base:out | ios_base:binary);os.write(reinterpret_cast(values), sizeof(values);os.close(); ifstream is(integers, ios_base:in | ios_base:binary);if (is) is.seekg(3 * sizeof(int);int v;is.read(reinterpret_cast(&v), sizeof(int);cout The 4th int
23、eger in the file integers is v endl; else cout ERROR: Cannot open file integers. endl;return 0;3011.3 输入流 11.3.4 输入流相关函数C+语言程序设计(第4版),郑莉,清华大学例11-11读一个文件并显示出其中0元素的位置/11_11.cpp, 头部分省略int main() ifstream file(integers, ios_base:in | ios_base:binary);if (file) while (file) /读到文件尾file为0 streampos here =
24、file.tellg(); int v; file.read(reinterpret_cast(&v), sizeof(int); if (file & v = 0) cout Position here is 0 endl; else cout ERROR: Cannot open file integers. endl;file.close();return 0;3111.3 输入流 11.3.4 输入流相关函数C+语言程序设计(第4版),郑莉,清华大学11.3.5 字符串输入流( istringstream) 用于从字符串读取数据 在构造函数中设置要读取的字符串 功能 支
25、持ifstream类的除open、close外的所有操作 典型应用 将字符串转换为数值3211.3 输入流C+语言程序设计(第4版),郑莉,清华大学例11-12用istringstream将字符串转换为数值/11_12.cpp, 头部分省略template inline T fromString(const string &str) istringstream is(str);/创建字符串输入流T v;is v;/从字符串输入流中读取变量vreturn v;/返回变量v int main() int v1 = fromString(5);cout v1 endl;double v2 =
26、 fromString(1.2);cout v2 ”、“”运算符,对账户信息重载“”运算符。35C+语言程序设计(第4版),郑莉,清华大学例11-13 个人银行账户管理程序 程序分为6个文件: date.h是日期类头文件 date.cpp是日期类实现文件 accumulator.h为按日将数值累加的Accumulator类的头文件 account.h是各个储蓄账户类定义头文件 account.cpp是各个储蓄账户类实现文件 11_13.cpp是主函数文件。3611.5综合实例对个人银行账户管理程序的改进C+语言程序设计(第4版),郑莉,清华大学/date.h#ifndef _DATE_H_#d
27、efine _DATE_H_#include class Date /日期类/Date类中不再有静态成员函数read,其它内容与例10-24完全相同,;std:istream & operator (std:istream &in, Date &date);std:ostream & operator (istream &in, Date &date) int year, month, day;char c1, c2;in year c1 month c2 day;date = Date(year, month, day);return in;o
28、stream & operator (ostream &out, const Date &date) out date.getYear() - date.getMonth() - date.getDay();return out;3711.5综合实例对个人银行账户管理程序的改进例11-13(续)C+语言程序设计(第4版),郑莉,清华大学/account.h#ifndef _ACCOUNT_H_#define _ACCOUNT_H_#include date.h#include accumulator.h#include #include #include class A
29、ccount /账户类/Account类中为以下函数增加了一个参数,其它成员与例10-24完全相同virtual void show(std:ostream &out) const;inline std:ostream & operator (std:ostream &out, const Account &account) account.show(out);return out;class CreditAccount : public Account /信用账户类/ CreditAccount类中为以下函数增加了一个参数,其它成员与例10-24完全相同vir
30、tual void show(std:ostream &out) const;/account.h中其它类的定义与例10-24完全一样#endif /_ACCOUNT_H_3811.5综合实例对个人银行账户管理程序的改进例11-13(续)C+语言程序设计(第4版),郑莉,清华大学/account.cpp中,只有以下几个成员函数的实现有所改变,其它内容与例10-24完全相同void AccountRecord:show() const cout date t# getId() t amount t balance t desc endl;Account:Account(const Dat
31、e &date, const string &id) : id(id), balance(0) cout date t# id created endl;void Account:show(ostream &out) const out id tBalance: balance;void CreditAccount:show(ostream &out) const Account:show(out);out tAvailable credit: getAvailableCredit();3911.5综合实例对个人银行账户管理程序的改进例11-13(续)C+语言程
32、序设计(第4版),郑莉,清华大学/11_13.cpp#include account.h#include #include #include #include #include #include using namespace std;struct deleter template void operator () (T* p) delete p; ;class Controller /控制器,用来储存账户列表和处理命令private:Date date;/当前日期vector accounts;/账户列表bool end;/用户是否输入了退出命令public:Controller(const
33、 Date &date) : date(date), end(false) Controller();const Date &getDate() const return date; bool isEnd() const return end; /执行一条命名,返回该命令是否改变了当前状态(即是否需要保存该命令)bool runCommand(const string &cmdLine);4011.5综合实例对个人银行账户管理程序的改进例11-13(续)C+语言程序设计(第4版),郑莉,清华大学Controller:Controller() for_each(accou
34、nts.begin(), accounts.end(), deleter();bool Controller:runCommand(const string &cmdLine) istringstream str(cmdLine);char cmd, type;int index, day;double amount, credit, rate, fee;string id, desc;Account* account;Date date1, date2;str cmd;switch (cmd) case a:/增加账户/ 对a(增加账户)、d(存款)、w(取款)、s(查询账户信息)、
35、c(改变日期)、/ n(进入下个月)的处理,与例10-24基本相同,只是把读入参数的输入流由cin改为了/ str,并且在每种情况后直接return,其中对s命令返回false,其它皆返回true。case q:/查询一段时间内的账目str date1 date2;Account:query(date1, date2);return false;case e:/退出end = true;return false;cout Inavlid command: cmdLine endl;return false;4111.5综合实例对个人银行账户管理程序的改进例11-13(续)C+语言程序设计(第4
36、版),郑莉,清华大学int main() Date date(2008, 11, 1);/起始日期Controller controller(date);string cmdLine;const char *FILE_NAME = commands.txt;ifstream fileIn(FILE_NAME); /以读模式打开文件if (fileIn) /如果正常打开,就执行文件中的每一条命令while (getline(fileIn, cmdLine)controller.runCommand(cmdLine);fileIn.close(); /关闭文件ofstream fileOut(FI
37、LE_NAME, ios_base:app);/以追加模式打开文件cout (a)add account (d)deposit (w)withdraw (s)show (c)change day (n)next month (q)query (e)exit endl;while (!controller.isEnd() /从标准输入读入命令并执行,直到退出cout controller.getDate() tTotal: Account:getTotal() ;string cmdLine;getline(cin, cmdLine);if (controller.runCommand(cmdL
38、ine)fileOut cmdLine endl;/将命令写入文件return 0;4211.5综合实例对个人银行账户管理程序的改进例11-13(续)C+语言程序设计(第4版),郑莉,清华大学 第一次运行结果 . (输入和输出与例9-16给出的完全相同) 第二次运行结果 2008-11-1 #S3755217 created 2008-11-1 #02342342 created 2008-11-1 #C5392394 created 2008-11-5 #S3755217 5000 5000 salary 2008-11-15 #C5392394 -2000 -2000 buy a cell
39、 2008-11-25 #02342342 10000 10000 sell stock 0323 2008-12-1 #C5392394 -16 -2016 interest 2008-12-1 #C5392394 2016 0 repay the credit 2008-12-5 #S3755217 5500 10500 salary 2009-1-1 #S3755217 17.77 10517.8 interest 2009-1-1 #02342342 15.16 10015.2 interest 2009-1-1 #C5392394 -50 -50 annual fee (a)add
40、account (d)deposit (w)withdraw (s)show (c)change day (n)next month (q)query (e)exit (后面省略) 第二次执行程序时,第一次输入的数据完全被恢复了4311.5综合实例对个人银行账户管理程序的改进例11-13(续)C+语言程序设计(第4版),郑莉,清华大学11.6.1 宽字符、宽字符串与宽流 普通字符和字符串的缺陷 一个汉字被拆成两个字符 例:string s = “这是一个中文字符串”; s.size():返回18 s.substr(3,2):得到的结果是“且” s.find(“且”):返回34411.6 深度探
41、索C+语言程序设计(第4版),郑莉,清华大学宽字符与宽字符串 宽字符:wchar_t类型 一般占2个字节,可以直接存下一个汉字 宽字符的文字以“L”开头,例: wchar_t c = L人; 宽字符串:wstring类型 与string同源 typedef basic_string string; typedef basic_string wstring; 例 wstring s = L这是一个中文字符串; s.size():返回94511.6 深度探索 11.6.1 宽字符、宽字符串与宽流C+语言程序设计(第4版),郑莉,清华大学宽流 宽流:以宽字符为基本单位的流 wistream、wifs
42、tream、wistringstream、wostream、wofstream、wostringstream、wios wcin、wcout、wcerr、wclog 宽字符和宽字符串需要通过宽流输入输出 宽流与普通流一一对应,彼此同源 typedef basic_ifstream ifstream; typedef basic_ifstream wifstream;4611.6 深度探索 11.6.1 宽字符、宽字符串与宽流C+语言程序设计(第4版),郑莉,清华大学为宽文件流配置编码方案 文件以字节为单位,编码方案决定了宽字符和字节的对应关系 例:L“ABCD”占4个字节,L“甲乙丙丁”占8个
43、字节,这由编码方案体现 配置方法: 用“代码页”编号构造locale对象 执行流的imbue成员函数 示例 locale loc(.936); /创建本地化配置方案对象 wcout.imbue(loc); /设置wcout对象的编码方案 wcout L这是一个中文字符串 endl;/输出字符串4711.6 深度探索 11.6.1 宽字符、宽字符串与宽流C+语言程序设计(第4版),郑莉,清华大学例11-14 用文件宽输入流查找文件中的“人”字/11_14.cpp,部分头文件引用省略#include using namespace std;int main() locale loc(.936);
44、/创建本地化配置方案wcout.imbue(loc);/为wcout设置编码方案wifstream in(article.txt);/创建文件宽输入流,打开文件article.txtin.imbue(loc);/为in设置编码方案wstring line;/用来存储一行内容unsigned number = 0;/记录行号while (getline(in, line) number+;/行号加1if (line.find_first_of(L人) != wstring:npos)/查找“人”字 wcout number L: line endl;/输出包含“人”字的行return 0;4811.6 深度探索 11.6.1 宽字符、宽字符串与宽流C+语言程序设计(第4版),郑莉,清华大学11.6.2 对象的串行化 串行化:将对象写入文件,使得在适当的时候对象能从文件中读出并恢复 直接用write将对象内容输出、用read将对象恢复的问题 对象中存在指针时,指针所指对象内容不会被保存; 对象的成员本身可能是存在指针的对象; 对象不仅是数据的集合,还包括一系列
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 劳务中包合同范本
- 课题立项申报书查重率
- 代理英文合同范本
- 加快老旧农机更新换代的实施方案
- 代写招标文件合同范例
- 合同范本买卖协议书
- 双方合作店铺合同范本
- 咨询顾问合同范本 英文缩写
- 保安兼职合同范本
- 仓库代发服务合同范本
- 中国大米等粮食项目投资可行性研究报告
- 2025语文新教材三下全册8个单元教材解读分析汇编
- java安全编码规范
- 美丽的春天课件
- 2025年山东青岛自贸发展有限公司招聘笔试参考题库含答案解析
- 液化气罐的使用和安全防范
- 2025年中考物理总复习《内能》专项测试卷含有答案
- 会计法律法规答题答案
- 2024年无锡工艺职业技术学院高职单招语文历年参考题库含答案解析
- 兽医检验测试题(附参考答案)
- 剧本杀范本完整版
评论
0/150
提交评论