zoukankan      html  css  js  c++  java
  • C++:IO标志位

    (部分摘自《标准C++输入输出流与本地化》)

    1. 状态标志.

        1). 每个流对象都维护一个状态变量标记流状态(成功或失败),该变量类型是iostate(实际上是ios_base定义的位域类型),状态变量的不同二进制位用来标记不同状态,共有三个状态标志:

    状态标志

    作用

    所占bit

    failbit

    出现可挽回的非致命错误

    1

    badbit

    出现不可挽回的致命错误

    2

    eofbit

    到达文件尾

    3

    goodbit

    没有错误

    不占bit

        2). 函数

    函数

    作用

    bool fail()

    若failbit位被置为1,返回true

    bool bad() 

    若badbit位被置为1,返回true  

    bool eof()

    若eofbit位被置为1,返回true

    bool good()

    若failbit,badbit,eofbit位全为0,返回true

    iostate rdstate() const

    获取当前流状态变量

    void clear (iostate state = goodbit)

    重设流状态为state,并覆盖原有状态,默认为ios:goodbit

    void setstate (iostate state)

    在原有状态基础上添加state状态,其实是clear(rdstate()|state)

    2. 格式标志.

        1). 除状态变量外,每一个流对象还维护一个fmtflags类型(与iostate类似)的格式变量,用来标记输入输出格式,格式标志有:

    位组

    格式标志

    作用

    默认值

    所占bit

    skipws

    使用输入操作符时跳过空白字符

    设置

    1

    unitbuf

    每次操作后刷新缓冲区

    Cerr设置,其他对象不设置

    2

    uppercase

    字母采用大写

    不设置

    3

    showbase

    输出整数时加上进制前缀

    未设置

    4

    showpoint

    按精度输出浮点数(不够补0)

    未设置

    5

    showpos

    输出非负数时加‘+’

    未设置

    6

    adjustfield

    left

    加入指定字符使输出左对齐

    right

    7

    right

    加入指定字符使输出右对齐

    8

    Internal

    在符号和数值中间插入指定字符

    9

    basefield

    dec

    10进制输入/输出

    dec

    10

    oct

    8进制输入/输出

    11

    hex

    16进制输入/输出

    12

    floatfield

    scientific

    浮点数按科学计数法输出

    无,由浮点数量级决定

    13

    fixed

    浮点数按小数输出

    14

    boolalpha

    以字母格式输入和输出布尔值

    未设置

    15

         (位组:有些标志位相互排斥,相互排斥的标记位属于同一位组,以便于对同一位组的标记位复位)

         2). 函数

    fmtflags flags() const

    获取当前格式变量

    fmtflags flags (fmtflags fmtfl)

    将格式变量设为fmtfl,并返回之前的格式变量

    fmtflags setf (fmtflags fmtfl)

    在原来格式基础上附加fmtfl,相当于flags(fmtfl|flags()).

    fmtflags setf (fmtflags fmtfl, fmtflags mask);

    将位组mask所包含的标记位清零,并置为fmtfl对应标记位的值,相当于flags((fmtfl&mask)|(flags()&~mask))

    void unsetf (fmtflags mask)

    清除位组mask的格式标记位

    streamsize width() const;

    获取当前域宽度

    streamsize width (streamsize wide);

    设置域宽度为wide

    streamsize precision() const;

    获取当前精度

    streamsize precision (streamsize prec);

    设置精度为prec

    char fill() const;

    获取当前的填充字符

    char fill (char fillch)

    设置输出宽度不满域宽时的填充字符为fillch,默认为空格

         注:在使用setf设置属于某一位组的标记位时,需要提供位组作为第二个参数来将其他互斥的标记位复位,否则可能会出现设置无效的现象.

        3). 使用2)的函数可以设置输入输出的格式,标准库还提供了"操纵符"(类似于函数)使得格式化输入输出更加方便,将操纵符作为<<和>>的右操作数使用可以直接设置输入输出格式,使用这些操纵符需要加头文件<iomanip>操纵符有:

    操纵符

    影响

    用途

    等价表示

    flush

    O

    刷新流缓冲区

    o.flush()

    endl

    O

    插入换行符并刷新缓冲区

    o.put(widen(‘ ’));

    o.flush();

    ends

    O

    插入串结束符

    o.out(o.widen((‘’));

    ws

    I

    抽取空白字符

    boolalpha

    I/O

    设置bool型的输入输出格式

    io.setf(ios_base::boolalpha)

    noboolalpha

    I/O

    复位上述标志

    io.unsetf(ios_base::boolalpha)

    showbase

    O

    设置用于整数前缀的标志

    o.setf(ios_base::showbase)

    noshowbase

    O

    复位上述标志

    o.unsetf(ios_base::showbase)

    showpos

    O

    为非负整数设置产生’+’的标志

    o.setf(ios_base::showpos)

    noshowpos

    O

    复位上述标志

    o.unsetf(ios_base::showpos)

    showpoint

    O

    按精度输出浮点数(不够补0)

    o.setf(ios_base::showpoint)

    noshowpoint

    O

    复位上述标志

    o.unsetf(ios_base::showpoint)

    skipws

    I

    设置跳过空白字符的标志

    i.setf(ios_base::skipws)

    noskipws

    I

    复位上述标志

    i.unsetf(ios_base::skipws)

    uppercase

    O

    大写输出字母

    o.setf(ios_base::uppercase)

    nouppercase

    O

    复位上述标志

    o.unsetf(ios_base::uppercase)

    unitbuf

    O

    设置每次格式化输出后刷新输出的标志

    o.setf(ios_base::unitbuf)

    nounitbuf

    O

    复位上述标志

    o.unsetf(ios_base::unitbuf)

    internal

    O

    设置在指定内部节点填充字符的标志

    o.setf(ios_base::interbal,ios_base::adjustfield)

    left

    O

    设置左对齐标志

    o.setf(ios_base::left,ios_base::adjustfield)

    right

    O

    设置右对齐标志

    o.setf(ios_base::right,ios_base::adjustfield)

    dec

    I/O

    按十进制转换整数

    io.setf(ios_base::dec,ios_base::basefield)

    hex

    I/O

    按十六进制转换整数

    io.setf(ios_base::hex,ios_base::basefield)

    oct

    I/O

    按八进制转换整数

    io.setf(ios_base::oct,ios_base::basefield)

    fixed

    O

    设置浮点数按定点表示标志

    o.setf(ios_base::fixed,ios_base::floatfield)

    scientific

    O

    设置浮点数按科学表示法表示标志

    o.setf(ios_base::scientific,ios_base::floatfield)

    setiosflags(ios_base::fmtflags mask)

    I/O

    根据mask设置格式标志

    io.setf(ios_base::fmtflags mask)

    setiosflags(ios_base::fmtflags mask)

    I/O

    根据mask清除格式标志

    io.unsetf(ios_base::fmtflags mask)

    setbase(int base)

    I/O

    为整数表示设置基数

    io.setf(base==8?ios_base::oct:base==10?ios_base::dec:base==16?ios_base::hex:ios_base::fmtflags(0),ios_base::basefield)

    setfill(char c)

    I/O

    设置填充字符

    io.fill(c)

    setprecision(int n)

    O

    设置精度

    io.precision(n)

    setw(int n)

    I/O

    设置最小字宽

    io.width(n)

         4). 正如以上所展示的,操纵符分为带参数和不带参数的,不带参数的操纵符本质上是具有特定参数和返回值类型的函数指针,带参数的操纵符本质上是重载了移位运算符的对象.

        自定义不带参数的操纵符,可以像这样:

    ios_base& boolalpha(ios_base& strm){
        strm.setf(ios_base::boolaplha);
        return strm;
    }
    //ios_base是所有io流类的基类
    View Code

        自定义带参数的操纵符,可以像这样:

    class width{
    public:
        explicit width(unsigned int i):i_(0){}
    private:
        unsigned int i_;
        template<class charT,class Traits>
        friend base_ostream<char T,Traits>&   operator<<(basic_ostream<charT,Traits>&ib,const width&w){
            ib.width(w.i_);
            return ib;
    }
    View Code

        关于自定义操纵符的具体细节,详见《标准C++输入输出流与本地化》3.2

    3. 文件打开方式标志

        1). 使用文件流类型时,可以在构造函数或open函数中指定打开方式,参数是ios_base::openmode类型(和iostate和fmtflags类似),以下是用于指定文件打开方式的标记位:

    名称

    作用

    所占bit

    app

    向文件尾增加数据

    1

    ate

    从文件尾部开始

    2

    binary

    以二进制方式读写

    3

    in

    以读方式打开文件

    4

    out

    以写方式打开文件

    5

    trunc

    清除文件内容(默认标志)

    6

        2). 可以使用|同时按多个模式打开文件,但并不是所有的打开方式都可以组合,下表是合法的组合:

    打开方式

    作用

    +ate标志

    +binary标志

    in

    in|trunc

    只读方式打开文件

    只读方式打开文件设文件长度为0

    初始文件位置指针在文件尾部

    抑制转换

    out

    out|trunc

    只写方式打开文件

    只写方式打开文件并设文件长度为0

    初始文件位置指针在文件尾部

    抑制转换

    out|app

    追加,尽在文件尾写入

    初始文件位置指针在文件尾部

    抑制转换

    in|out

    读写均可

    初始文件位置指针在文件尾部

    抑制转换

    int|out|trunc

    读写均可并设文件长度为0

    初始文件位置指针在文件尾部

    抑制转换

        3). 其他注意事项

            1''. 输出文件流默认打开方式为ios_base::out|ios_base::trunc,输入文件流默认打开方式为ios_base::in|ios_base::trunc,也就是说,对于单项文件流trunc标志位是默认设置的,但双向文件流默认打开方式为ios_base:in|ios_base::out,默认不设置trunc标志位

            2''. ate(ate-end)和app,都是将文件指针定位在文件尾,不同之处在于,ate模式允许修改文件指针位置,app模式强制将指针定位到文件尾,即使修改指针位置也无效.

  • 相关阅读:
    pip 8 安装
    zabbix server配置文件
    双代号网络图、双代号时标网络图
    logrotate
    tsql 执行存储过程
    dos 加用户
    Visual Studio (VS IDE) 你必须知道的功能和技巧
    格式化数字字符串 与C#变量
    .NET中的字符串你了解多少?
    新手如何有效地学习.NET
  • 原文地址:https://www.cnblogs.com/reasno/p/4875656.html
Copyright © 2011-2022 走看看