只记录常用的,为的就是少翻砖头书·········

IO类:

       IO类顾名思义就是用来做IO的,包括普通流(iostream处理控制台IO)、文件流(fstream处理文件IO)、string流(sstream完成内存中string的IO)。平时用到的 cin 和 cout 分别是 istream 和 ostream 的一个对象。文件流和string流都是继承于普通流,所以适用于普通流的操作同样适用于文件流和string流。另外要注意的是,流对象不能被赋值和拷贝,所以我们会发现有关流的函数中其参数或者返回值都是对流的引用。

类与所在的头文件:

iostream                                 istream、wistream        从流读取数据

                                                ostream、wostream     向流写入数据

                                                iostream、wiostream   读写流

fstream                                    ifstream、wifstream    从文件读取数据

                                                ofstream、wofstream  向文件读取数据

                                                fstream、wfstream       读写文件

sstream                                   istringstream、wistringstream    从string读取数据

                                                ostringstream、wostringstream  向string写入数据

                                                stringstream、wstringstream       读写string

       上面有些类前面加了w,这是对应类的宽字符版本,照常使用就行了。

条件状态:

       IO操作可能会发生错误,一些错误可以恢复,另一些错误是由于系统原因造成的,无法恢复。通常,读取到的数据的类型与期望读取的类型不一致时,流会进入错误状态,流遇到文件结束符时也会进入错误状态,还有其他未知的操作也可能导致流进入错误状态。一个流如果在读取某个数据时发生了错误,其上后续的IO操作都将会失败。所以,我们在使用一个流之前,或者在流读取一部分数据之后接着要继续读取数据之前,应该检查流是否处于正常状态。检查流是否正常的最简单做法就是把流当做一个条件来使用:

    while( cin ) {.........} //或者 

    if( cin ) {.............}

花括号内代表流处于正常状态时要进行的操作。另外IO类还提供了许多状态位和函数来帮助我们查询流的状态:

strm::iostate        //strm是一种上面列出的IO类型,iostate是一种机器相关的类型,提供了表达条件状态的完整功能

strm::badbit        //用来指出流已崩溃

strm::failbit         //用来指出一个IO操作失败了

strm::eofbit         //用来指出流已到达了文件结束

strm::goodbit     //用来指出流未处于错误状态,此值保证为零

s.eof()                 //若流 s 的eofbit置位,则返回true

s.fail()                 //若流 s 的 failbit 或 badbit 置位,则返回true

s.bad()                //若流 s 的 badbit 置位,则返回true

s.good()             //若流 s 处于有效状态,则返回true

s.clear()              //将流 s 中所有条件状态位复位,将流的状态设置为有效,返回void

s.clear(flags)       //根据给定的 flags 标志位,将流 s 中对应条件状态位复位。flags的类型为strm::iostate。返回void

s.setstate(flags) //根据给定的 flags 标志位,将流 s 中对应的条件状态位置位。flags的类型同上。返回void

s.rdstate()          //返回流 s 的当前条件状态,返回值类型为 strm::iostate

       记录《C++Primer第五版》中280页的话:badbit表示系统级错误,如不可恢复的读写。通常情况下,一但badbit被置位,流就无法再使用了。在发生可恢复错误后,failbit被置位,如期望读取数值却读取出一个字符等错误。这种问题是可以修正的,流还可以继续被使用。如果到达文件结束位置,eofbit和failbit都会被置位。goodbit的值为0,表示流为发生错误。如果badbit、failbit和eofbit任一个被置位,则检测流状态的条件会失败。

       good()在所有错误位均未置位的情况下返回true,而bad()、fail()和eof()则在对应错误位被置位时返回true。在badbit被置位是,fail()也会返回true。使用good()和fail()是确定流的总体状态的正确方法。

格式化输入输出:

boolalpha                    //用输出true和false来代替布尔值1和0

no boolalpha                //反上

oct                                //以八进制输出整数

dec                               //以十进制输出整数

hex                               //以十六进制输出整数

showbase                    //输出数制的前导符,如八进制是0,十六进制是0x

noshowbase                //反上

uppercase                    //输出十六进制时涉及到的字母全部变大写

nouppercase                //反上

cout.precision()            //获取当前输出浮点数的精度

cout.precision(p)          //设置浮点数输出的精度为p

文件输入输出:

       前面适用于普通IO流的操作也适用于文件流,包括<<、>>、getline()等。除此之外还提供了以下操作,可以对fstream、ifstream、ofstream调用这些操作:

fstream fstrm;                    //创建一个未绑定的文件流。fstream是头文件fstream中定义的一个类型

fstream fstrm(s);                //创建一个fstream,并打开名为 s 的文件。s 可以是string类型,或者是一个指向C风格字符串的指针。这些构造

                                           //函数都是explicit的。默认的文件模式mode依赖于fstream的类型。

fstream fstrm(s,mode);      //按指定的mode打开文件名为 s 的文件。

fstrm.open(s);                    //打开名为 s 的文件,并将文件与fstrm绑定。 s 可以是string类型,或者是指向C风格字符串的指针。

                                           //默认的文件mode依赖于fstream的类型。返回void

fstrm.close();                      //关闭与fstrm绑定的文件。返回void

fstrm.is_open();                  //返回一个bool值,指出与fstrm关联的文件是否成功打开且尚未关闭。

fstrm.read(start,length);    //从当前文件指针处开始读入length个字节的数据放到start所指的缓冲区

fstrm.write(start,length);    //将start所指的缓冲区往后length个字节写入到文件中。

       所以,要使用文件流打开文件有两种做法:

fstream file("filename");    //直接用文件名构造流对象

fstream file;

file.open("filename");        //先声明一个流对象,再用open来关联

       文件流对象同样可以作为条件,用来判断文件打开是否成功以及文件流对象的状态是否有效。如果一个文件已经被打开但未关闭,当再次使用open()来打开另一个文件时,文件流对象将会进入错误状态,并且failbit被置位,导致之后的IO操作都失效。必须先调用close()来关闭文件才可以打开另一个文件。一个文件流对象在析构时会自动调用close()函数解除与文件的关联。

文件模式:

in            //以读方式打开

out         //以写方式打开

app        //每次写操作前均定位到文件末尾

ate         //打开文件后立即定位到文件末尾

trunc      //截断文件

binary    //以二进制方式进行IO

       ifstream不能被指定out模式,ofstream不能被指定in模式。ofstream默认以out模式打开文件,并且隐含有trunc模式,即以写模式打开文件,文件内存会被截断,即被覆盖。若不想打开的文件被覆盖,可以以app模式构建ofstream对象来打开文件,这样数据只会写到文件末尾而不会覆盖文件。trunc模式不能与app同时使用。

文件随机访问:

tellg();                    //返回一个输入流中标记的当前位置

tellp();                    // 类上,改为输出

seekg(pos);            //在一个输入流中将标记重定位到pos给定的绝对地址

seekp(pos);             // 类上,改为输出

seekp(off,form);    //在一个输出流中将标记定位到from之前或之后off个字符的位置,from可以是beg(文件开始)、cur(当前)、

                              //end(文件末尾)之一。

seekg(off,form);    //类上,改为输入

       巧用 seek(0,end) 与 tellg() 的组合可以很方便地得到文件的长度。

string流:

       这个东西跟string有什么区别?string流可以向cin和cout那样用>>和<<来读写,而string却不能。string流对象内部也有一个string对象,只是增加了<<和>>而已。没什么好神秘的。使用与普通IO流的操作也适用于string流。

相关操作:

sstream strm;        //strm是一个未绑定的stringstream对象。sstream是头文件sstream中定义的一个类型。

sstream strm(s);    //strm是一个sstream对象,保存string s 的一个拷贝。次构造函数是explicit的。

strm.str();              //返回strm所保存的string的拷贝

strm.str(s);            //将string s 拷贝到strm 中。返回void

       顺便记记string。

string对象:

初始化string对象的方式:

string s1;                    //默认初始化,是s1是一个空串

string s2(s1);              //s2是s1的副本

string s2 = s1;            //同上

string s3("value");      //s3是字面值"value"的副本,除了字面值最后的那个空字符外

string s3 = "value";    //同上

string s4(n,'c');            //把s4初始化为由连续n个字符c组成的串

string的操作:

os<<s;            //将s写到输出流os当中,并返回os

is>>s;             //从is输入流中读取字符串赋给s,并返回 is。在执行读取操作时,string对象会自动忽略开头的空白,包括空格符、换行符、

                       //制表符等,并从第一个真正的字符开始读起,直到遇见下一处空白为止。

getline(is,s);   //从 is 输入流中读取一行赋给s,返回 is。遇到空格不断流,可以读入空格,但一遇到换行符,读取结束。

                       //注意换行符虽然被读进来了,但没有保存到string中

s.empty();       //s为空串则返回true,否则返回false 

s.size();           //返回s中字符的个数 

s[n];                //返回s中第n个字符的引用,位置n从0算起

s1+s2;            //返回s1和s2连接后的结果、string对象也能与字面值连接,但是两个字面值字符串不能直接用'+'连接

s1=s2;            //用s2的副本代替s1中原来的字符

s1==s2;          //如果s1和s2中所含的字符完全一样,则它们相等;string对象的相等性判断对字母的大小写敏感

s1 != s2;

<,<=,>,>=    //利用字母在字典中的顺序进行比较,且对字母的大小写敏感

读取未知长度的流:

string word;
 
 
while( cin>>word )            //每次读入一个单词,并在循环体内输出。直到遇到文件结束符或非法输入就结束。
 
 
    cout<< word << endl;
 
 
 
 
string line;
 
 
while( getline(cin, line) )    //与上面类似,换成一次读入一行
 
 
    cout<< line << endl;

       流对象之所以能作为条件,是因为编译在背后做了隐式类型转换,调用了流对象中的bool运算符重载函数,返回的bool值代表流对象是否正常。一般来说,非法输入、文件结束符等因素都会导致其返回false。