C++面向对象(四十四)格式化输入输出

#include <iostream>
#include <iomanip>
using namespace std;

/*
格式化输入输出: 在实际工作中, 需要按特定格式进行输入输出. 
C++的I/O流类库提供了两种控制格式输入输出的方法:
1 使用ios类的成员函数进行格式控制: 
(1) 使用ios类成员函数设置标志字: ios类中声明了一个数据成员, 用于记录当前流的格式化状态, 这个数据成员被称为标志字.
标志字的每一位用于记录一种格式. 为了便于记忆, 为每一种格式定义了对应的枚举量. 在程序中可以使用标准常量或直接用对应的十六进制
值设置输入输出流的格式. ios类有几个成员函数可以设定格式标志字, 域宽, 填充字符以及输出精度来控制输入输出的格式,

格式控制常量及含义:

ios有几个直接操作标志字的公有成员函数:
long flags(): 该函数用来返回标志字
long flags(long): 该函数使用参数值来更新标志字, 并返回更新前的标志字
long setf(long setbits, long field): 该函数用来将field所指定的标志位清零, 将setbits为1的标志位置为1, 并返回设置前的标志字
long setf(long): 该函数用来设置参数所指定的标志位, 并返回更新前的标志字
void unsetf(long): 该函数用来清除参数所指定的标志位

流格式标志字每一位表示一种格式, 格式位直接会有依赖关系:
dec, oct和hex在同一时刻只能有一个位被设置, 所以设置一个位之前应该清除其他有排斥的位, 为了便于清除同类排斥位, ios定义了几个
用于作为setf(long setbits, long field)的第二个参数field的公有静态符号常量:
static const long ios::basefield: dec| oct| hex
static const long ios::adjustfield: left| right| internal
static cosnt long ios::floatfield: scientific| fixed

(2) 使用ios类成员函数设置域宽, 填充字符及输出精度: 在ios类还定义了设置域宽, 填充字符和输出精度的成员函数:
<1> 设置输出数据所占宽度的函数:
int width(): 该函数用来返回当前输出的数据宽度
int width(int): 该函数用来设置输出的数据宽度, 并返回更新前的宽度值
注意事项: 
<1>.1 默认值为输出该数据所需的最小字符数
<1>.2 如果设置的域宽小于数据所需的最小字符数, 采用默认宽度
<1>.3 只对一个数据的输出有效, 需要不断设置

<2> 设置当前宽度内的填充字符的函数:
char fill(): 该函数用来返回当前所使用的填充字符.
char fill(char): 该函数用类设置当前填充字符为参数所表示的字符, 并返回更新前的值
注意事项:
<2>.1 默认填充字符为空格

<3> 设置浮点数输出精度函数:
int precision(): 该函数用来返回当前浮点数的有效数字的个数
int precision(int): 该函数用来设置当前浮点数输出时的有效数字个数为该函数的参数值, 并返回更新前的值
注意事项:
<3>.1 单精度浮点数(float)有效数字个数最多为7个, 双精度浮点数(double)有效数字个数最多为15个, 长双精度浮点数(long double)
有效数字个数最多为19个

2 使用控制符(操作子)控制进行格式控制
C++的I/O流类库提供了一种使用控制符进行格式输出的方法, 这种方法比前面的方法操作起来简单.控制符域成员函数调用的效果
一致, 但是可以直接插入, 不必单独调用, 还可以直接被插入符和提取符操作, 但是控制符没有实现的功能还需要通过调用成员函数
实现, 其本质是特殊的函数, 其中不带形式参数的函数在头文件iostream.h中定义, 带形式参数的函数则定义在iosmanip.h中

I/O流类库定义的控制符

*/

void test1();

void test2();

void test3();

void test4();

void test5();

void test6();


int main()
{
    //test1();

    //test2();

    //test3();

    //test4();

    //test5();
    
    system("pause");

}

/*
ios使用控制符控制输入输出格式
*/
void test6()
{
    cout << "oct form of 15 is " << oct << 15 << endl;
    cout << dec << 10 << endl;
    cout << setbase(16) << "hex form of 32 is " << 31 << endl;
    cout << "hex form of 32 is " << setw(8) << setfill('*') << setiosflags(ios::left | ios::showpos) << 31 << endl;
    cout << setprecision(3) << setw(8) << 15.456f << endl;
    cout << setprecision(3) << setw(8) << resetiosflags(ios::left) << 15.445f << endl;
}


/*
ios成员函数控制域宽, 填充字符和数据精度
*/
void test5()
{
    char a[] = "hello world";
    cout << a << endl;
    cout.width(20);
    cout << a << endl;
    cout.fill('-');
    cout.width(20);
    cout << a << endl;
    cout.setf(ios::left);
    cout.width(20);
    cout << a << endl;
    cout.fill(' ');
    cout.width(20);
    cout << a << endl;
    cout.setf(ios::internal, ios::adjustfield);
    cout.setf(ios::showpos);
    cout.width(20);
    cout.precision(6);
    cout.fill('_');
    cout << 12.34 << endl;
}


/*
ios成员函数清除排斥位, 并重新设置
*/
void test4()
{
    int a = 1024;
    cout.setf(ios::showbase);
    cout << "a = " << a << endl;
    long flags = cout.flags();
    cout << "flags = " << flags << endl;
    flags = cout.setf(ios::oct, ios::basefield);
    cout << "a = " << a << endl;
    cout << "flags = " << flags << endl;
    flags = cout.setf(ios::hex, ios::basefield);
    cout << "a = " << a << endl;
    cout << "flags = " << flags << endl;
}

/*
ios成员函数返回标志字的值
*/
void test3()
{
    long flags = cout.setf(ios::left | ios::oct);
    cout << "flags = " << flags << endl;
    flags = cout.setf(ios::oct | ios::showbase);
    cout << "flags = " << flags << endl;
    flags = cout.setf(ios::showpoint | ios::fixed);
    cout << "flags = " << flags << endl;
    cout.unsetf(ios::showpoint | ios::fixed);
    flags = cout.flags();
    cout << "flags = " << flags << endl;
}

///ios成员函数setf(long| long|...)多个标志常量在setf函数中做参数一起设置标志字的值, 使用"|"分隔
void test2()
{
    double a = 12.34;
    cout << "a = " << a << endl;
    //long flags = cout.setf(ios::showpos | 0x1000);
    long flags = cout.setf(0x1000 | ios::showpos);
    cout << "flags = " << flags << endl;
    cout << "a = " << a << endl;
}

//ios成员函数setf(long)分别设置标志字的不同位
void test1()
{
    double a = 12.34;
    cout << "a = " << a << endl;
    //设置标志字, 使正数的输出带"+", 使用标志常量ios::showpos(0x0400)设置显示"+"
    //使用变量flags接收修改前的值
    long flags = cout.setf(ios::showpos);
    //long flags = cout.setf(0x0400);
    cout << "flags = " << flags << endl;

    //设置标志字, 使浮点数以科学计数法的形式输出, 使用标志常量ios::scientific(0x1000)设置浮点数显示形式为科学计数法形式
    flags = cout.setf(0x1000);
    flags = cout.setf(ios::scientific);
    cout << "flags = " << flags << endl;
    cout << "a = " << a << endl;
}

 

格式化输入输出: 在实际工作中, 需要按特定格式进行输入输出.
C++的I/O流类库提供了两种控制格式输入输出的方法:
1 使用ios类的成员函数进行格式控制:
(1) 使用ios类成员函数设置标志字: ios类中声明了一个数据成员, 用于记录当前流的格式化状态, 这个数据成员被称为标志字.
标志字的每一位用于记录一种格式. 为了便于记忆, 为每一种格式定义了对应的枚举量. 在程序中可以使用标准常量或直接用对应的十六进制
值设置输入输出流的格式. ios类有几个成员函数可以设定格式标志字, 域宽, 填充字符以及输出精度来控制输入输出的格式,
格式控制常量及含义:

 

 

 
ios有几个直接操作标志字的公有成员函数:
long flags(): 该函数用来返回标志字
long flags(long): 该函数使用参数值来更新标志字, 并返回更新前的标志字
long setf(long setbits, long field): 该函数用来将field所指定的标志位清零, 将setbits为1的标志位置为1, 并返回设置前的标志字
long setf(long): 该函数用来设置参数所指定的标志位, 并返回更新前的标志字
void unsetf(long): 该函数用来清除参数所指定的标志位
流格式标志字每一位表示一种格式, 格式位直接会有依赖关系:
dec, oct和hex在同一时刻只能有一个位被设置, 所以设置一个位之前应该清除其他有排斥的位, 为了便于清除同类排斥位, ios定义了几个
用于作为setf(long setbits, long field)的第二个参数field的公有静态符号常量:
static const long ios::basefield: dec| oct| hex
static const long ios::adjustfield: left| right| internal
static cosnt long ios::floatfield: scientific| fixed
(2) 使用ios类成员函数设置域宽, 填充字符及输出精度: 在ios类还定义了设置域宽, 填充字符和输出精度的成员函数:
<1> 设置输出数据所占宽度的函数:
int width(): 该函数用来返回当前输出的数据宽度
int width(int): 该函数用来设置输出的数据宽度, 并返回更新前的宽度值
注意事项:
<1>.1 默认值为输出该数据所需的最小字符数
<1>.2 如果设置的域宽小于数据所需的最小字符数, 采用默认宽度
<1>.3 只对一个数据的输出有效, 需要不断设置
<2> 设置当前宽度内的填充字符的函数:
char fill(): 该函数用来返回当前所使用的填充字符.
char fill(char): 该函数用类设置当前填充字符为参数所表示的字符, 并返回更新前的值
注意事项:
<2>.1 默认填充字符为空格
<3> 设置浮点数输出精度函数:
int precision(): 该函数用来返回当前浮点数的有效数字的个数
int precision(int): 该函数用来设置当前浮点数输出时的有效数字个数为该函数的参数值, 并返回更新前的值
注意事项:
<3>.1 单精度浮点数(float)有效数字个数最多为7个, 双精度浮点数(double)有效数字个数最多为15个, 长双精度浮点数(long double)
有效数字个数最多为19个
2 使用控制符(操作子)控制进行格式控制
C++的I/O流类库提供了一种使用控制符进行格式输出的方法, 这种方法比前面的方法操作起来简单.控制符域成员函数调用的效果
一致, 但是可以直接插入, 不必单独调用, 还可以直接被插入符和提取符操作, 但是控制符没有实现的功能还需要通过调用成员函数
实现, 其本质是特殊的函数, 其中不带形式参数的函数在头文件iostream.h中定义, 带形式参数的函数则定义在iosmanip.h中
I/O流类库定义的控制符

 

 

 

代码示例:

 

posted @ 2020-09-06 13:08  DNoSay  阅读(408)  评论(0编辑  收藏  举报