• 8.3 C++格式标识和操纵器


    参考:http://www.weixueyuan.net/view/6409.html

    总结:

      我们需要借助格式标识符来控制cout对象的输出格式。

      在ios_base类中,系统已经定义了很多格式标识符,通过这些标识符,我们可以很好地进行格式化控制,具体见下表。ios_base类中还定义有width和precision等函数。

      除了能够直接调用这些格式标识符之外,我们可以借助类中提供的成员函数。

      这些函数都是ios_base类的成员函数,可以通过对象直接调用,而cout是basic_ostream的一个对象,basic_ostream继承自ios_base,因此cout可以调用这些函数。

      ios_base::showbase,即显示基数,基数的意思就是说在十六进制前加上0x,在八进制前加上0,十进制则不作处理。

      一旦格式设置完成,则会一直保持格式,除非取消格式,因此在设置新格式前最好将原有设置的格式都取消。

      这些格式化控制除了可以使用格式标识来控制外,我们还可以使用操纵器来控制。

      操作器其本质是函数,它可以直接改变流的格式。  

      C++标准库中预定义了一些操纵器,使用其中带参数的操纵器则需要包含头文件iomanip,下标中列出了一些带参数的操纵器。

    ----------------------------------

    在我们设计程序时,我们通常需要将输出数据以某种格式显示出来,例如我们希望将时间显示为“dd:dd:dd”的形式,如此一来我们就需要借助格式标识符来控制cout对象的输出格式。在ios_base类中,系统已经定义了很多格式标识符,通过这些标识符,我们可以很好地进行格式化控制,具体见下表。除此之外,ios_base类中还定义有width和precision等函数,这些函数同样可以辅助我们进行格式化控制。

    格式标识符用途
    boolalpha 以true和false的形式读写bool类型变量
    dec 以十进制的方式进行读写
    oct 以八进制的方式进行读写
    hex 以十六进制的方式进行读写
    internal 放在正负号或基数标识之后
    left 左对齐
    right 右对齐
    fixed 以定点方式表示浮点数
    scientific 用科学计数法表示浮点数
    showbase 输出时显示基数
    showpoint 必须显示小数点
    showpos 对非负数显示+号
    skipws 忽略空格
    unitbuf 写操作完成后清扫所有的缓冲区
    uppercase 用大写字母表示十六进制
    adjustfield 格式标识必须是left、right或internal
    basefield 格式标识必须是dec、oct或hex
    floatfield 格式标识必须是scientific或fixed


    有了表中所列标识符我们确实可以进行格式控制,但是除了能够直接调用这些格式标识符之外,我们可以借助类中提供的成员函数,具体成员函数见下表。

    成员函数用途
    flags() 返回当前的格式标识
    flags( val ) 将格式标识设置为val,并返回旧值
    setf ( val ) 将val设置为当前的格式标识,并返回旧的格式标识
    setf ( val, ios_base::basefield ) 将val设置为当前的格式标识,并返回旧的格式标识,且要求val为iso_base::dec、ios_base::hex或ios_base::oct三者之一
    setf ( val, ios_base::adjustfield ) 将val设置为当前的格式标识,并返回旧的格式标识,且要求val为iso_base::left、ios_base::internal或ios_base::right三者之一
    setf ( ios_base::internal, ios_base::adjustfield ) 在符号与数据之间填充字符,并返回旧标识
    setf ( ios_base::scientific,
    ios_base::floatfield )
    设置科学计数法并返回旧标识
    setf ( ios_base::fixed,
    ios_base::floatfield )
    设置定点计数法并返回旧标识
    setf ( 0, ios_base::floatfield ) 设置默认浮点数表示法并返回旧标识
    unsetf ( val ) 清楚指定的标识并返回旧标识

     
    这些函数都是ios_base类的成员函数,可以通过对象直接调用,而cout是basic_ostream的一个对象,basic_ostream继承自ios_base,因此cout可以调用这些函数。

    例1:

    #include<iostream>
    using namespace std;
    
    int main()
    {
        ios_base::fmtflags old_val = cout.flags( ios_base::left | ios_base::hex |ios_base::uppercase | ios_base::showbase );
    
        for( int i = 100; i < 150; i ++ )
            cout << i << endl;
        cout<<endl<<endl;   
        cout.unsetf ( ios_base::left | ios_base::hex |ios_base::uppercase );
    
        cout.setf ( old_val );
        for( int i = 100; i < 150; i ++ )
            cout << i << endl;       
        cout<<endl<<endl;
        cout.unsetf( old_val );
    
        cout.setf ( ios_base::hex | ios_base::uppercase );
        cout << " hex " << 170 << endl;
        cout.unsetf( ios_base::hex | ios_base::uppercase );
        cout.setf ( ios_base::oct );
        cout << " oct " << 170 << endl;
        cout.unsetf( ios_base::oct );
        cout.setf ( ios_base::dec );
        cout << " dec " << 170 << endl;
    
        return 0;
    }

    本例中我们先调用flags函数设置输出格式,格式设置为左对齐和大写的十六进制,之后我们将100~149的数字全部输出,输出完之后我们将刚才设置的格式全部取消,然后重新设置为原始的格式old_val,再将数字100~149的数字重新输出一遍。之后我们演示的是将170按照十六进制、八进制和十进制的形式输出。

    在整个程序中由于我们一开始设置了ios_base::showbase,即显示基数,基数的意思就是说在十六进制前加上0x,在八进制前加上0,十进制则不作处理。我们一开始设置了ios_base::showbase后,一直没有取消设置,因此在整个程序输出过程中一直都是加上了基数。出现这种情况也是我们要注意的,一旦格式设置完成,则会一直保持格式,除非取消格式,因此在设置新格式前最好将原有设置的格式都取消。

    例2:

    #include<iostream>
    using namespace std;
    
    int main()
    {
        cout.width ( 6 );
        cout << -100 << endl;
    
        cout.setf( ios_base::left ,ios_base::adjustfield);
        cout.width ( 6 );
        cout << -100 << endl;
        cout.unsetf( ios_base::left );
    
        cout.setf( ios_base::right ,ios_base::adjustfield);
        cout.width ( 6 );
        cout << -100 << endl;
        cout.unsetf( ios_base::right );
    
        return 0;
    }

      

    在本例中我们调用成员函数width控制输出的宽度为6个字符的位置,之后我们分别设置左对齐和右对齐,然后输出-100。从上面程序中我们可以看出默认是采用右对齐的方式输出的。

    当然,这些格式化控制除了可以使用格式标识来控制外,我们还可以使用操纵器来控制,下面我们来简单了解一下操纵器。操作器其本质是函数,它可以直接改变流的格式。

    例3: 

    cout << hex << uppercase << " hex " << 170 << endl;
    cout << oct << " oct " << 170 << endl;
    cout << dec << " dec " << 170 << endl;

     

    本例中hex、oct、dec和uppercase都是操纵器,它可以与输入或输出操作符一起使用。

    C++标准库中预定义了一些操纵器,使用其中带参数的操纵器则需要包含头文件iomanip,下标中列出了一些带参数的操纵器。

    格式标识符作用对象功能
    setbase( int n ) basic_ostream 将n设置为基数(默认值为0)
    setfill( char_type c ) basic_ostream 设置填充字符为c
    setprecision( int n ) basic_ostream 设置精度为n
    setw( int n ) basic_ostream 设置域宽为n
    setiosflags( val ) ios_base 设置指定的标识
    resetiosflags( val ) ios_base 清除指定的标识


    表中列出的最后两个函数,其参数值为标识,即为格式标识符的组合。

  • 相关阅读:
    codeforces 455B A Lot of Games(博弈,字典树)
    HDU 4825 Xor Sum(二进制的字典树,数组模拟)
    hdu 1800 Flying to the Mars(简单模拟,string,字符串)
    codeforces 425A Sereja and Swaps(模拟,vector,枚举区间)
    codeforces 425B Sereja and Table(状态压缩,也可以数组模拟)
    HDU 4148 Length of S(n)(字符串)
    codeforces 439D Devu and Partitioning of the Array(有深度的模拟)
    浅谈sass
    京东楼层案例思维逻辑分析
    浅谈localStorage和sessionStorage
  • 原文地址:https://www.cnblogs.com/yongpan/p/7994383.html
Copyright © 2020-2023  润新知