infile.open(“in”); outfile.open(“out”);
检查文件打开是否成功: if (!infile) {
cerr << “error: unable to open input file:” << ifile << endl; return -1; }
fstream对象一旦打开,就保持与指定的文件相关联,如果要把fstream对象与另一个不同的文件关联,则必须先关闭(close)现在的文件,然后打开(open)另一个文件: ifstream infile(“in”); infile.close();
infile.open(“next”);
如果需要重用文件流读取多个文件,必须在读另一个文件前调用clear清除该流的状态。 文件模式 见 37 文件模式.png
in-----------打开文件做读操作 out--------打开文件做写操作
app-------在每次写之前找到文件尾
ate-------打开文件后立即将文件定位在文件尾 trunk----打开文件时清空已存在的文件流 binary---以二进制模式进行IO操作
out,trunc,app模式只能用于指定与ofstream或fstream对象关联的文件,in模式只能用于指定与ifstream或fstream对象关联的文件,所有的文件都可以用ate或binary模式打开,ate模式只在打开时有效:文件打开后将定位在文件尾。以binary模式打开的流则将文件以字节序列的形式处理,而不解释流中的字符。
从效果来看,为ofstream对象指定out模式等效于同时指定了out和trunc模式。
fstream对象即可以读也可以写与它关联的文件,fstream如何如何使用它的文件取决于打开文件时指定的模式。 默认情况下,fstream对象以in和out模式同时打开,当文件同时以in和out打开时不清空。 如果打开fstream所关联的文件时,只使用out模式,而不指定in模式,则文件会清空也存在的数据,如果打开文件时指定了trunc模式,则无论是否同时指定了in模式,文件同样会被清空。如:下面定义将copyout文件同时以输入和输出的模式打开: fstream inOut (“copyOut”, fstream::in | fstream::out);
默认时,与ifstream流对象关联的文件将以in模式打开,该模式允许文件做读操作,与ofstream关联的文件则以out模式打开,使文件可写,以out模式打开的文件会被清空,丢失该文件存储的所有数据。 ofstream outfile;
outfile.open(“scratchpad”, ofstream::out);
outfile.close();
只要调用open函数,就要设置文件模式,其模式的设置可以是显示的也可以是隐式的,隐式时将使用其默认值。
打开文件的有效组合 38 文件模式的组合.png
out out | app out | trunk in in | out in | out |trunk 一个打开并检查输入文件的程序:
ifstream& open_file (ifstream& in, const string &file) {
in.close(); in.clear();
in.open(file.c_str()); return in; }
iostream标准库也支持内存中的输入/输出操作,只要将流与存储在程序内存中的string对象捆绑起来即可,此时,可使用iostream输入和输出操作符读写这个string对象,标准库定义了三种类型的字符串流:
istringstream---------------------提供读string的功能 ostringstream--------------------提供写string的功能 stringstream----------------------提供读写string的功能 要使用上述类,必须包含sstream头文件。
fstream和sstream共享相同的基类,但它们没有其他的相互关系,特别是,stringstream对象不能使用open和close函数,而fstream对象则不允许使用str。 stringstream特定的操作 见 39 stringstream特定的操作.png
stringstream strm; stringstream strm(s); strm.str(); strm.str(s); stringstream对象的使用: string line, word;
while (getline(cin, line)) { //do per-line processing istringstream stream(line); while (stream >> word) { // do per-dord procdssing } }
stringstream对象的一个常见用法是,需要在多种数据类型之间实现自动格式化时使用该类类型。
int val1 = 512, val2 = 1024; ostringstream format_message;
format_message << “val1:” << val1 << “\\n”
<< “val2” << val2 <<”\\n”;
相反,用istringstream读string对象,即可重新将数值类型数据找回来: istringstream input_istring(format_message.str()); input_string dump;
input_istring >> dump >> val1 >> dump >>val2; cout << val1 << “” << val2 << endl; 第九章 顺序容器
顺序容器类型:vector 支持快速随机访问;list 支持快速插入删除;deque 双端队列 顺序容器适配器:stack 后进先出栈;queue 先进先出队列;priority_pueue有优先级管理的队列
容器只定义了少量操作,大多数额外操作则是由算法库提供。 容器元素的初始化:见7容器构造函数.png
将一个ring器初始化为另一个容器的副本: vector
不能直接将一种容器内的元素复制给另一种容器,但系统类允许通过传递一对迭代器间接实现该功能。使用迭代器时,不要求容器类型相同,容器内的元素也可以不相同。只要它们相互兼容,能够将要复制的元素转换为所要求构建的新的容器的元素类型即可实现复制。 分配和初始化指定数目的元素: const list
list
元素类型必须支持赋值运算和元素类型的对象必须可以复制。 容器的容器:vector< vector
*iter iter-> ++iter(iter++) --iter(iter--) iter1 == iter2 iter1 != iter2
除了上面的运算外,vector和deque类型迭代器支持以下操作见9vector和deque类型迭代器支持的操作.png
iter + n iter – n iter1 += iter2 iter1 -+ iter2 iter1 – iter2 > >= < <=
vector中可以使用以下方法计算vector对象中点的位置: vector
c++语言使用一对迭代器标记迭代器范围,如:[first, last) 容器定义的类型别名见:12容器定义的类型别名
容器的begin和end操作:见13容器的begin和end操作.png
在顺序容器中添加元素的方法:见 14 在顺序容器中添加元素的方法.png
c.push_back(t) c.push_front(t) c.insert(p, t) c.insert(p, n, t) c.insert(p, b, e) 任何insert或者push操作都可能导致迭代器失效,程序必须每次循环后都保证迭代器得到更新。
不要存储end操作返回的迭代器,添加或者删除deque或vector容器内的元素都会导致存储的迭代器失效:如:
vector
first = v.insert (first, 23); ++ first; }
为了避免存储end迭代器,可以在每次做完插入运算后重新计算end迭代器的值: while (first != v.end()) {
first = v.insert (first, 23);