【C++ Primer】第八章 文件的输入输出
来源:互联网 发布:windows10还原网络设置 编辑:程序博客网 时间:2024/05/23 11:15
一、IO对象不可复制或赋值
出于某些原因,标准库类型不允许做复制或赋值操作。比如,
ofstream out1,out2;out1 = out2; //error:cannot assign stream objects//print function: parameter is copiedofstream = print(ofstream);out2 = print(out2); //error:cannot copy stream objects
1)只有支持复制的元素类型可以存储在vector或其他容器类型里。由于流对象不能复制,因此不能存储在vector(或其他)容器中(即不存在存储流对象的vector或其他容器)。
2)形参或返回类型也不能为流类型。如果需要传递或返回IO对象,则必须传递或返回指向该对象的指针或引用:
ofstream &print(ofstream&); //ok:takes a reference, no copywhile (print(out2) ) {/*...*/} //ok:pass reference to out2
一般情况下,如果要传递IO对象以便对它进行读写,可用非const引用的方式传递这个流对象。对IO对象的读写会改变它的状态,因此引用必须是非const的。
二、流的条件状态
IO标准库管理一系列条件状态(condition state)成员,用来标记给定的IO对象是否处于可用状态。
- s.eof() end-of-file,文件结束符
- s.good() 如果流s处于有效状态,则该函数返回true
- s.clear() 将流s中的所有状态值都设为有效状态
- s.clear(flag) 将流s中的某个指定条件状态设置为有效。flag的类型是strm::iostate
- s.setstate(flag) 给流s添加指定条件。
- s.rdstate() 返回流s的当前条件
clear和setstate操作用于改变条件成员的状态。clear操作将条件重设为有效状态。在流的使用出现了问题并做出补救后,如果我们希望把流重设为有效状态,则可以调用clear操作。使用setstate操作可打开某个指定的条件,用于表示某个问题的发生。
流的状态邮bad、fail、eof和good操作揭示。如果bad、fail或eof中的任一个为true,流本身将处于错误状态。
1.条件状态的访问
rdstate成员函数返回一个iostate类型的值,该值对应于流当前的整个条件状态:
//remenber current state of cinistream::iostate old_state = cin.rdstate();cin.clear();process_input(); //use cincin.clear(old_state); //now reset cin to old state
三、输出缓冲区的管理
每个IO对象管理一个缓冲区,用于存储程序读写的数据。
os<<"please enter a value:";
系统将字符串字面值存储在与流os关联的缓冲区中。下面几种情况将导致缓冲区的内容被刷新:
1)程序正常结束。作为main返回工作的一部分,将清空所有输出缓冲区。
2)在一些不确定的时候,缓冲区可能已经满了,在这种情况下,缓冲区将会在写下一个值之前被刷新。
3)用操作符显式的刷新缓冲区,例如行结束符endl。
4)在每次输出操作执行完后,用unitbuf操纵符设置流的内部状态,从而清空缓冲区。
5)可将输出流与输入流关联(tie)起来。在这种情况下,在读输入流时将刷新其关联的输出缓冲区。
1.输出缓冲区的刷新(flush、ends、endl)
cout<<"hi"<<flush; //flushes the buffer;adds no datacout<<"hi"<<ends; //inserts a null,then flushes the buffercout<<"hi"<<endl; //inserts a newline,then flushes the buffer
2.unitbuf操作符
如果需要刷新所有输出,最好使用unitbuf操作符。这个操作符在每次执行完写操作后都刷新流:
cout<<unitbuf<<"first"<<"second"<<nounitbuf;
等价于:
cout<<"first"<<flush<<"second"<<flush;
nounitbuf操作符将恢复为使用正常的、由系统管理的缓冲区刷新方式。
note:程序崩溃后不会刷新缓冲区
四、文件的输入和输出
C++中的文件名:
由于历史原因,IO标准库使用C风格字符串而不是C++ string类型的字符串作为文件名。在创建fstream对象时,如果调用open或使用文件名作初始化式,需要传递的实参应为C风格字符串,而不是标准库string对象。程序常常从标准输入获得文件名。通常,比较好的方法是将文件名读入string对象,而不是C风格字符数组。假设要使用的文件名保存在string对象中,则可调用c_str成员获取C风格字符串。
1.文件流对象的使用
需要读写文件时,则必须定义自己的对象,并将它们绑定在需要的文件上。假设ifile和ofile是存储希望读写的文件名的string对象:
//construct an ifstream and bind it to the file named ifileifstream infile(ifile.c_str());//ofstream output file object to write file named ofileofstream outfile(ofile.c_str());
infile和ofile分别是读文件的流对象和写文件的流对象
以上是在定义的时候直接初始化打开一对fstream对象。若开始未初始化,如下:
ifstream infile; //unbound input file streamofstream outfile; //unbound output file stream
上面定义的两对象均未绑定具体文件。在使用fstream对象之前,还必须使这些对象捆绑要读写的文件:
infile.open("in"); //open file named "in" in the current directoryoutfile.open("out"); //open file named "out" in the current directory
调用open成员函数将已存在的fstream对象与特定文件绑定。
将文件与新文件流重新绑定
ifstream infile("in");infile.close();infile.open("next");
在尝试打开新文件之前先关闭当前的文件流
五.字符串流
标准库string类型
#include <string>
using std::string;
string对象的定义和初始化
- string s1; 默认构造函数,s1为空串
- string s2(s1); 将s2初始化为s1的一个副本
- string s3("value"); 将s3初始化为一个字符串字面值副本
- string s4(n,'c'); 将s4初始化为字符'c'的n个副本
Note:因为历史原因以及为了与C语言兼容,标准库string类型和字符型字面值不是同一种类型
string对象的读写
cin>>s;
从标准输入读取string,并将读入的串存储在s中。string类型的输入操作符:
- 读取并忽略开头所有的空白字符(如空格,换行符,制表符)。
- 读取字符直至再次遇到空白字符,读取终止。
因此,如果输入到程序的是“ hello world! ”,屏幕上将输出“hello”,而不含任何空格。
1.stringstream对象的使用
string line, word; //will hold a line and word from input,respectivelywhile(getline(cin, line)) { //read a line from the input into line //do per-line processing istringstream stream(line); //bind to stream to the line we read while(stream>>word) { //read a word from line //do per-word processing }}这里使用getline函数从输入读取整行内容。然后为了获得每行中的单词,将一个istringstream对象与所读取的行绑定起来,这样只需使用普通的string输入操作符即可读出每行中的单词。
2.stringstream提供的转换和/或格式化
int val1 = 512, val2 = 1024;ostringstream format_message;//ok:converts values to a string representationformat_message<<"val1: "<<val1<<"\n" <<"val2: "<<val2<<"\n";
format_message里面的内容是以下字符:
val1: 512\nval2: 1024
用istringstream读string对象
//str member obtains the string associated with a stringstream istringstream input_istring(format_message.str()); string dump; //place to dump the labels from the formatted message //extracts stored ascii values,converting back to arithmetic types input_istring>>dump>>val1>>dump>>val2; cout<<val1<<" "<<val2<<endl; //print 512 1024这里使用str成员获取与之前创建的ostringstream对象关联的string副本,再将input_istring与string绑定起来。
C++使用标准库类处理输入和输出:
iostream类处理面向流的输入和输出。
fstream类处理已命名文件的IO。
stringstream类处理内存中字符串的IO。
- 【C++ Primer】第八章 文件的输入输出
- C++primer 第八章
- c++primer 第八章
- C++primer(第五版)第八章IO库(简单的介绍输入输出的IO库)
- C primer plus 第八章 字符输入输出与输入验证 编程练习 个人答案
- 《C++ Primer》读书笔记第八章-2-文件输入输出 And string流
- 【足迹C++primer】22、文件输入输出
- C++primer习题第八章
- C++primer第八章课后变成练习的小问题
- c++primer 第八章IO操控流的条件状态
- 【c++】文件的输入输出
- C++primer 第八章学习小记
- c primer Plus第八章笔记
- 《C Primer Plus》第八章编程题
- C++Primer读书笔记(第八章)
- c primer plus 第八章答案
- c++primer第五版第八章练习
- C primer plus 第八章 练习1:
- 接口与抽象类的区别
- 在android上访问本地服务器
- Delphi读取jpg文件的问题
- 摩尔定理
- Windows Embedded CE 4.2/5.0/6.0开发工具下载大全
- 【C++ Primer】第八章 文件的输入输出
- 移动付费demo分析
- Java学习笔记
- 计算机硬件的发展
- 我学会了坚持,seo吧
- OpenCV的otsu自适应阈值分割的算法在肤色检测中的应用
- Oracle操作技巧
- ACM图灵奖
- 大病