[Turn] C++ cout formatted output

[Turn] C++ cout formatted output

Transfer from here

Sometimes you want to output according to a certain format, such as outputting integers in hexadecimal, leaving two digits after the decimal point when outputting floating-point numbers, outputting integers in the width of 6 digits, and padded 0 on the left when the width is insufficient, and so on. The printf() function in C language uses %format control symbols that begin with, such as %X, %.2f, %6d, etc.; the cout object in C++ uses stream operators (you can also call format control symbols) or members Function to control.

Use stream operators

Commonly used output stream manipulation operators in C++ are shown in Table 1. They are all defined in the header file iomanip; to use these stream manipulation operators, the header file must be included.

Note: The asterisk in the "Flow Manipulation Operator" column is *not a part of the operator. The asterisk means that if no operator is used, it is equivalent to using the operator. For example, by default, integers are output in decimal form, which is equivalent to using the dec operator.

Flow operator Use
*dec Output integer in decimal form Commonly used
hex Output integers in hexadecimal form
oct Output integer in octal form
fixed Output floating point numbers as ordinary decimals
scientific Output floating point numbers in scientific notation
left Left-justified, that is, fill characters are added to the right when the width is insufficient
*right Right-aligned, that is, when the width is insufficient, fill characters are added to the left
setbase(b) Set the base when outputting integers, b=8, 10 or 16
setw(w) Specify the output width as w characters, or read w characters when inputting a character string
setfill © When the output width is specified, when the output width is insufficient, the character c is used to fill (the default is to fill with spaces)
setprecision(n) Set the precision of the output floating point number to n. In the case of non-fixed and non-scientific output, n is the number of significant digits. If the number of significant digits exceeds n, the fractional part will be rounded off, or it will be automatically converted to scientific notation for output and kept in total n significant digits. In the case of fixed and scientific output, n is the number of digits that should be kept after the decimal point.
setiosflags(flag) Set a certain output format flag to 1
resetiosflags(flag) Set an output format flag to 0
boolapha Output true and false as strings uncommonly used
* noboolalpha Output true and false as 0, 1
showbase Output the prefix of the base of the value
*noshowbase Do not output the prefix of the base.
showpoint Always output decimal point
*noshowpoint Display the decimal point only when the decimal part exists
showpos Show in non-negative values ​​+
*noshowpos Do not display in non-negative values ​​+
* skipws Skip blank characters when typing
noskipws Do not skip blank characters when typing
uppercase Use A~E in hexadecimal number. If the prefix is ​​output, the prefix outputs 0X, and the output E in scientific notation
*nouppercase Use a~e in hexadecimal numbers. If the prefix is ​​output, the prefix outputs 0x, and in scientific notation, it outputs e.
internal The sign (plus or minus) of the value is left aligned within the specified width, the value is aligned right, and the middle is filled with padding characters.

How to use stream operators

The way to use these operators is to use << and cout together. E.g:

cout << hex << 12 << "," << 24;

The function of this statement is to specify the following two numbers to be output in hexadecimal form, so the output result is:

c, 18

setiosflags () operator

The setiosflags() operator is actually a library function. It takes some flags as parameters. These flags can be the following values ​​defined in the iostream header file. Their meaning is the same as the operator of the same name.

Sign Use
ios::left The output data is aligned to the left within the wide range of this field
ios::right The output data is aligned to the right within the wide range of this field
ios::internal 数值的符号位在域宽内左对齐,数值右对齐,中间由填充字符填充
ios::dec 设置整数的基数为 10
ios::oct 设置整数的基数为 8
ios::hex 设置整数的基数为 16
ios::showbase 强制输出整数的基数(八进制数以 0 开头,十六进制数以 0x 打头)
ios::showpoint 强制输出浮点数的小点和尾数 0
ios::uppercase 在以科学记数法格式 E 和以十六进制输出字母时以大写表示
ios::showpos 对正数显示“+”号
ios::scientific 浮点数以科学记数法格式输出
ios::fixed 浮点数以定点格式(小数形式)输出
ios::unitbuf 每次输出之后刷新所有的流
ios::stdio 每次输出之后清除 stdout, stderr

这些标志实际上都是仅有某比特位为 1,而其他比特位都为 0 的整数。

多个标志可以用|运算符连接,表示同时设置。例如:

cout << setiosflags(ios::scientific|ios::showpos) << 12.34;

输出结果是:

+1.234000e+001

如果两个相互矛盾的标志同时被设置,如先设置 setiosflags(ios::fixed),然后又设置 setiosflags(ios::scientific),那么结果可能就是两个标志都不起作用。因此,在设置了某标志,又要设置其他与之矛盾的标志时,就应该用 resetiosflags 清除原先的标志。例如下面三条语句:

cout << setiosflags(ios::fixed) << 12.34 << endl;
cout << resetiosflags(ios::fixed) << setiosflags(ios::scientific | ios::showpos) << 12.34 << endl;
cout << resetiosflags(ios::showpos) << 12.34 << endl;  //清除要输出正号的标志

输出结果是:

12.340000
+1.234000e+001
1.234000e+001

综合示例

关于流操纵算子的使用,来看下面的程序。

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    
    
    int n = 141;
    //1) 分别以十六进制、十进制、八进制先后输出 n
    cout << "1)" << hex << n << " " << dec << n << " " << oct << n << endl;
    double x = 1234567.89, y = 12.34567;
    //2)保留5位有效数字
    cout << "2)" << setprecision(5) << x << " " << y << " " << endl;
    //3)保留小数点后面5位
    cout << "3)" << fixed << setprecision(5) << x << " " << y << endl;
    //4)科学计数法输出,且保留小数点后面5位
    cout << "4)" << scientific << setprecision(5) << x << " " << y << endl;
    //5)非负数显示正号,输出宽度为12字符,宽度不足则用 * 填补
    cout << "5)" << showpos << fixed << setw(12) << setfill('*') << 12.1 << endl;
    //6)非负数不显示正号,输出宽度为12字符,宽度不足则右边用填充字符填充
    cout << "6)" << noshowpos << setw(12) << left << 12.1 << endl;
    //7)输出宽度为 12 字符,宽度不足则左边用填充字符填充
    cout << "7)" << setw(12) << right << 12.1 << endl;
    //8)宽度不足时,负号和数值分列左右,中间用填充字符填充
    cout << "8)" << setw(12) << internal << -12.1 << endl;
    cout << "9)" << 12.1 << endl;
    return 0;
}

程序的输出结果是:

1)8d 141 215
2)1.2346e+06 12.346
3)1234567.89000 12.34567
4)1.23457e+06 1.23457e+01
5)***+12.10000
6)12.10000****
7)****12.10000
8)-***12.10000
9)12.10000

需要注意的是,setw() 算子所起的作用是一次性的,即只影响下一次输出。每次需要指定输出宽度时都要使用 setw()。因此可以看到,第 9) 行的输出因为没有使用 setw(),输出的宽度就不再是前面指定的 12 个字符。

在读入字符串时,setw() 还能影响 cin 的行为。例如下面的程序:

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    
    
    string s1, s2;
    cin >> setw(4) >> s1 >> setw(3) >> s2;
    cout << s1 << "," << s2 << endl;
    return 0;
}

输入:

1234567890↙

程序的输出结果是:

1234,567

说明setw(4)使得读入 s1 时,只读入 4 个字符,其后的setw(3)使得读入 s2 时只读入 3 个字符。

setw() 用于 cin 时,同样只影响下一次的输入。

思考题:setw() 究竟是如何实现的,以至于能和 cout 连用来指定输出宽度?自行查看编译器所带的 iomanip 头文件,然后写一个功能和 setw() 完全相同的 mysetw()。

调用cout的成员函数

ostream 类有一些成员函数,通过 cout 调用它们也能用于控制输出的格式,其作用和流操纵算子相同,如表 3 所示。

成员函数 作用相同的流操纵算子 说明
precision(n) setprecision(n) 设置输出浮点数的精度为 n。
width(w) setw(w) 指定输出宽度为 w 个字符。
fill© setfill © 在指定输出宽度的情况下,输出的宽度不足时用字符 c 填充(默认情况是用空格填充)。
setf(flag) setiosflags(flag) 将某个输出格式标志置为 1。
unsetf(flag) resetiosflags(flag) 将某个输出格式标志置为 0。

setf 和 unsetf 函数用到的flag,与 setiosflags 和 resetiosflags 用到的完全相同。

这些成员函数的用法十分简单。例如下面的三行程序:

cout.setf(ios::scientific);
cout.precision(8);
cout << 12.23 << endl;

输出结果是:

1.22300000e+001

Guess you like

Origin blog.csdn.net/weixin_44338712/article/details/108411414