C++IO系统学习

来源:互联网 发布:javascript脚本怎么写 编辑:程序博客网 时间:2024/05/17 07:52

继承关系图:

ios_base介绍:

    ios_state是个枚举类型(就像open_mode一样,枚举类型意味着值只能有其一),C++中IO系统负责记录每一个输入输出操作结果信息,这些当前状态信息被包含在io_state类型的对象中,下面前三个标志位整体构成了流的状态(若三个均为0,表示流状态正常,反之,若有一个为1,流状态非正常):

标记位

(数据成员)

描述----0表示清除(正常),1表示设置

测试相应的标志位函数(函数成员)

eofbit

已到达文件尾

bool bad();

failbit

非致命的IO错误,可挽回

bool eof();

badbit

致命的IO错误,无法挽回,

bool fail();

goodbit

测试流状态是否正常,正常返回true,输出1。否则输出0。

bool good();

    注意:eofbit,failbit ,badbit,goodbit均为变量,它与当前的流状态有关。

    ios::eofbit\ios::failbit\ios::badbit\ios::goodbit均为常量,类型为iostate(本质上是bitmask类型,即由三位二进制表示的),它们任何一个都代表了一种流状态,因此称为“输入状态标记位常量”。下面是表示流状态的四个常量:

常量

含义

eofbit值

failbit值

badbit值

转化为10进制

ios::eofbit

已经到达文件尾

1

0

0

1

ios::failbit

IO流出现非致命错误,可挽回

0

1

0

4

ios::badbit

IO流出现致命错误,不可挽回

0

0

1

2

ios::goodbit

流状态完全正常

0

0

0

0

    注意: ios::eofbit, ios::failbit ,ios::badbit, ios::goodbit均为常量,它与当前的流状态无关。

流状态的影响:

异常流状态:

    exceptions()/exceptions(iosstate)/,有参数时设置哪个位将引发clear()异常。即clear()方法将当前的流状态与exceptios()方法的返回值进行对比,如果当前流状态的对应位与exceptions设置的对应位一致,则引发clear()异常。

设置(重置)流状态:

(1)clear()/clear(flag)函数;

    voidclear( iostate flags = goodbit );/ /默认使用ios::goodbit进行对应位逐位的相与操作。

    void clear( iostate flags );//flags选取四个标志位常量中的一个,进行对应位逐位的相与操作。

    clear()方法将当前的流状态与exceptios()方法的返回值进行对比,如果当前流状态的对应位与exceptions设置的对应位一致,则引发clear()异常。

(2)setstate(flag)函数

    参数为一个strm::iostate类型的值。如: cin.setstate(ios::eofbit);注意,它的目的是将标志位eofbit置1而其他位保持不变,即100与当前流状态的三个标志位的对应的逐位相或操作。(话说本质上还是用的clear函数,原理本人还没有弄明白,但应该如此,因为他也会与exceptions函数作用抛出异常)

测试流状态:

(1)本质上是用三个标志位对应的函数来测试当前的流状态。即用状态标志位相应的测试函数。

(2)rdstate()函数【函数成员】:返回值是将二进制转换为对应的十进制的数值。即是eofbit,failbit,badbit三个标志的值,返回的是一个strm::iostate类型。

(3)用流本身来测试:即根据cin和cout等流对象的返回值确定,后面有详细讲述。

basic_ios介绍:

创建/关闭流:

    void open( const char *filename );

    void open( constchar *filename, openmode mode );

    自然的关闭流就是voidclose();

    如果open()失败,当用于一个布尔表达式中时,作为结果的流会给出对错误的评估。

openmode mode模式

含义

ios::in

为读取打开文件

ios::out

为写入打开文件

ios::binary

以二进制模式打开文件

ios::trunk

覆盖存在的文件

ios::app

在末尾添加输出

ios::ate

当已打开时寻找到EOF,即将指针放到末尾

    在这里注意这个组合:ios::in| ios::out,以读写方式打开。流可以同时创建好几个,如输入输出一块创建,并且c++自动进行了同步管理。

istream介绍:

  istream很重要的一个实例化对象就是cin。

(1)重载>>:

  原型:istream& operator>>(类型 &);//这里的类型值得是内置基本类型以及char *。

  由原型可知>>返回的类型为istream&,举例:cin>>’H’>>”ello!”<<endl;即cin>>’H’返回istream对象的引用,这里返回的是cin,以此类推,顾可实现连续输入。很自然,<<提取符原理依然如此。

(2)get、read方法

(2.1)get方法,为键盘设计

(2.1.1)get(void)/get(char&);【istream成员函数】

    提供不跳过空白、制表符、换行符的单字符输入功能。

    int get(void);// 返回值是int类型,顾不可连续调用。将输入字符转换为整型。到达文件末尾时,cin.get(void)将返回一个整型EOF(C++定义的一个常量)。

    istream & get(char &)//返回值依然是istream &类型。将输入字符赋值给参数。while(cin.get(ch))该方法调用setstate(failbit)函数导致测试结果为false。

(2.2.2)get(char *,int)/get(char*,int,char)【istream成员函数】

    提供字符串的输入功能。

    原型:istream & get(char*,int)/ istream & get(char *,int,char);//返回值是istream &类型。参数1是指向字符串的首地址,参数2读取字符串个数+1,超过时将停止,参数3制定用作分界符的字符,没有参数3则默认为换行符为分界符,遇到分界符时将停止输入。

    附:第三类get()函数和getline()函数区别

    注意1:分界符不会留在流中,getline函数则遇到分界符抽取后停止并从并剔除这个分界符。

    注意2:意外输入处理方式都是把空字符串放到字符串中,并使用setstate()函数设置failbit。第三类get()函数当输入为空行或一开始就是文件尾或读取完毕后改行还有其他字符时发生。getline()函数只当一开始遇到文件尾时发生(因为getline()仍抽取空行换行符)。

(2.2)read方法,为文件设计

    istream &read( char *buffer, streamsize num ); 将字符放入buffer 之前从流中读取num 个字节。如果碰到EOF,read()中止,丢弃不论多少个字节已经放入。

    附:为该方法配套的方法还有putback、peek方法

    istream &putback( char ch ); 将字符插到输入字符串中且被插入字符是下一条输入语句读取的第一个字符。

    int peek();返回输入流中下一个字符但不抽取,如是处于文件结尾处返回EOF。相当于先get后putback原位置。

(3)输入流指针

  (3.1)seekg()重新设置"get"指针到当前流的从origin偏移offset个字节的位置上,或是置"get"指针在position位置。

    istream &seekg( off_type offset, ios::seekdir origin );
    istream &seekg( pos_type position );
 (3.2)tellg()函数用于输入流,并返回流中"get"指针的当前位置。
    pos_type tellg();

ostream介绍

(1)重载<<

    省略,见前面istream介绍。

(2)put、write方法

(2.1)put方法,为键盘设计

    用于输出单个字符。【ostream成员函数】

    ostream& put(char);后来被模板化,返回ostream&类型,可连续调用。

(2.2)write方法,为文件设计

    用于输出字符串。【ostream函数成员】

    模版原型:basic_ostream<charT,traits>& write(const char_type* s,streamsize n);注意:write()函数在打完字符串还没有达到函数参数中的个数要求,接着会打印相邻内存的存储的数据。另外,假设参数1变成了一个long数值型数据(4字节),该方法会将逐个字节的值变换为ASCII码对应的字符,然后输出。

    附:为该方法配套的还有flush()和endl()函数【ostream函数】

    ostream & flush(ostream &)函数会刷新缓冲区。可用函数使用,也可用flush关键字使用。

    ostream & endl(ostream &)函数会刷新缓冲区并输出个换行符。可用函数使用,也可用endl关键字使用。

(3)输出流指针

   (3.1) seekp()将重新设置"get"指针到当前流的从origin偏移offset个字节的位置上,或是置"get"指针在position位置。

  ostream &seekp( off_type offset, ios::seekdir origin );
  ostream &seekp( pos_type position );

   (3.2) tellp()函数用于输出流中,并返回在流中当前"put"指针的位置。

    pos_type tellp();

    举例代码如下:

    strings("In Xanadu did Kubla Khan...");

      ofstream fout("output.txt");

      for( int i=0; i < s.length(); i++ ) {

        cout << "File pointer: "<< fout.tellp();

        fout.put( s[i] );

        cout << " " << s[i]<< endl;

    }

    fout.close();

ifstream和ofstream介绍

    ifstream和ofstream具有cin/cout的大部分特征,这些都是从基类集成过来的,一样使用。过程如下:

    创建一个类似于cin/cout的输入/输出对象,例如fin/fout。ifstreamfin;/ofstream fout;

    将对象如fin/fout与文件连接起来。fin.open(“text.txt”);//注意,这里也可合并成ifstreamfin(“text.txt”);/fout一样

    以cin/cout方式使用对象fin。fin>>/fout<<

    将对象如fin/fout与文件断开连接。fin.close();fout.close();

    注意,在关闭之前有时候用到clear()函数。

格式化输入输出:

    C++在输出中永远不会截断数据,如果试图在2字节宽度中打印7字节数据,c++会扩充宽度以容纳该数据。

    C++为标准输入和输出定义了一些格式标志, 它可以通过flags(),setf(), 和 unsetf() 三个函数来控制.

 

<iostream>中定义的操作符(既可以hex(cout),也可以凑他<<hex;)

setf第二个参数

操作符

描述

输入

输出

 

ios_basic::(no)boolalpha

(关闭)启用boolalpha标志,即输入输出(不)可以为(1/0)true/false

X

X

ios_basic::basefiled

ios_basic::oct

启用 oct 标志,8进制

X

X

ios_basic::dec

启用dec标志,10进制

X

X

ios_basic::hex

启用 hex 标志,16进制

X

X

ios_basic::floatfiled

ios_basic::fixed(scientific)

启用fixed(scientific)标志,一般浮点表示法(科学表示法)

 

X

ios_basic::adjustfield

ios_basic::left(right)

启用 left(right) 标志,左对齐(右对齐)

 

X

 

ios_basic::flush

清空流

 

X

 

ios_basic::endl

输出换行标示,并清空缓冲区

X

 

ios_basic::ends

输出空字符

X

 

ios_basic::ws

跳过所有前导空白字符

X

 

 

ios_basic:: (no)skipws

(关闭)开启skipws标志,即是否忽略空白,如’\n’

X

 

 

ios_basic:: (no)showpos

(关闭)关闭showpos 标志,即是否在正数前面加上+

 

X

 

ios_basic:: (no)showbase

(关闭)启用 showbase 标志,即是否显示进制基数前缀

 

X

 

ios_basic:: (no)showpoint

(关闭)启用 showpoint 标志,即是否显示末尾的小数点

 

X

 

ios_basic:: (no)uppercase

(关闭)开启uppercase 标志,即对于16进制输出是否使用大写字母

X

 

在<iomanip>中定义的操作符

操作符

描述

输入

输出

(re)setiosflags( long f )

(关闭)打开被指定为f的标志

X

X

setfill( int ch )

设置填充字符为ch

X

setw( int w )

设置域宽度为w

 

X

setprecision( int p )

设置数值的精度

X

setbase( int base )

设置数值的基本数为base

 

X

 

(1)flags函数

 fmtflags flags();

 fmtflags flags( fmtflags f );

 函数flags()返回当前流的格式标志,或者为当前流设置标志为f。

(2)setf函数

 fmtflags setf( fmtflags flags );

 fmtflags setf( fmtflags flags, fmtflags needed );

 函数setf()设置当前流的格式化标志为flags。可选标志needed 只允许flags标志和needed标志都被设置。返回值是前面设置的标志。

(3)unsetf函数

 void unsetf( fmtflags flags );

 函数unsetf()用于清除与当前流相关的给定的标志flags。

(4)width函数

  intwidth();

  intwidth( int w );

 函数 width()返回当前的宽度。可选择参数w用于设定宽度大小。宽度是指每一次输出中显示的字符的最小数目。设置后只影响接下来显示的项目,然后便恢复默认。

(5)fill函数

 char fill();

 char fill( char ch );

 函数fill()可以返回当前填充字符,或者设置当前填充字符为ch 。填充字符被定义为用来填充字符,当一个数字比较指定宽度T小时。默认的填充字符是空格。设置后一直有效,除非被重置。

(6)precision函数

 streamsize precision();

 streamsize precision( streamsize p );

 precision()函数设置或返回当前要被显示的浮点变量的位数。设置后一直有效,除非被重置。

参看文档:

《C++ primer plus》

《C++编程思想》

  C++API

0 0
原创粉丝点击