C++ 格式化IO

引言

昨天笔试腾讯后,收获不少,虽然比上次网易的情况略好一些,但是感觉自己的coding能力还是不够,在高压力情况下的心理素质不过关。本文顺带总结一下笔试中遇到的C++格式化输出问题,当时由于紧张和对知识的不熟悉,对这道简单的格式化输出竟然留了空白,真是太亏了。下面开始正文。
C++一般采用cout进行格式化输出,包含头文件< iomanip >可以实现几乎所有你想要的格式化输出。主要包括:

  1. 操纵不同类型的格式
  2. 浮点数输出精度和科学计数法
  3. 定宽输出(包括填充符号)
  4. 未格式化流的读取

    操纵不同类型的格式

    对于不同类型的格式,可以使用操作符改变格式状态。

    整型变量

    可以按不同进制输出:

int val = 17;
cout<<oct<<val<<endl; //输出21
cout<<hex<<val<<endl; //输出11
cout<<dec<<val<<endl; //输出17

//可以使用showbase操作符显示进制
cout<<showbase;
cout<<oct<<val<<endl; //输出021
cout<<hex<<val<<endl; //输出0x11
cout<<dec<<val<<endl; //输出17
cout<<noshowbase;//关闭显示进制

注意,这些操纵符会改变内部状态,对之后的输出也会产生影响。

布尔型变量

可以使用boolalpha操作符改变cout输出bool变量的格式,如:


cout<<boolalpha;
cout<<true<<endl;//输出true
cout<<false<<endl;//输出false
cout<<noboolalpha;

浮点型变量

对于浮点型变量我们可以控制几种格式,包括:

  1. 浮点数精度
  2. 输出进制和是否采用科学计数法
  3. 对于没有小数的部分是否打印小数点

浮点数精度可以通过setprecision操纵符或改变cout.precision的值来控制,如:

cout  <<sqrt(2)<< endl; //默认保持6位精度(包括整数部分),故输出1.41421
cout << setprecision(4) <<sqrt(2)<< endl;//输出1.414
//当浮点数小树部分为0,可以使用showpoint操纵符显示小数部分,如果浮点数显示未达到当前精度,也可以使用showpoint来补全小数后的0
cout  <<setprecision(4)<<showpoint<<17.0<< endl;//输出17.00

浮点数也能指定输出的进制和是否采用科学计数法,默认输出为小写字母,可以采用uppercase改为大写输出:

cout<<hexfloat<<17.0<<endl;//输出0x1.100000p+4
cout<<scientific<<17.0<<endl;//输出1.700000e+001
//注意,通过scientific或hexfloat或fixed(默认十进制)操作符后,会改变精度的定义,精度将定义为小数点后的位数,而默认为总位数

输出补白

处理数据时,我们经常需要对齐数据,因此定宽输出和补白是一种很常用的功能。C++提供了setw,setfill,left,right,internal等操作符控制输出的对齐和补白,如:

int val = 10;
cout<<setw(8)<<val<<endl;//输出      10
//默认右对齐用空白字符补白
cout<<setw(8)<<left<<setfill('#')<<val<<endl;//输出 10######
//我们通过left操作符将输出改为左对齐,setfill操作符更改默认的补白字符
cout<<setw(8)<<internal<<setfill('#')<<showpos<<val<<endl;//输出+#####10
//这里主要解释一下internal操作符和showpos操作符,对于数值型输出时,使用internal操作符将在符号与数值之间补白,而showpos操作符则显示正数的符号,因此就得到了上述输出。

需要注意的是,setw不改变内部状态,它只决定下一个输出的宽度。

扫描二维码关注公众号,回复: 912888 查看本文章

控制输入格式

默认情况下,cin会跳过空白符,制表符,回车符,换行符,换页符,可以通过操作符noskipws读取空白符:

char c;
while(cin>>c)
    cout<<c;
//输入"ab    c  d",输出abcd
while(cin>>noskipws>>c)
    cout<<c;

//输入"ab    c  d",输出ab    c  d

未格式化IO

之前我们提到的输入输出都是利用>>或者<<根据读取或输入的数据类型进行格式化。
标准库还提供了对未格式化数据的IO操作,这些操作将数据当作字节序列进行处理。

单字节操作

未格式化IO提供get和put分别用于输入和输出单个字符,他们也会读取空白字符,因为未格式化的操作来说,每个字符只是没有意义的数字而已:


        char c;
        while (cin.get(c))
            cout.put(c);//能够读取空白符,回车符等所有字符

若想一次性读取大块未格式化的数据,可以使用get的重载函数cin.get(sink,size,delimiter) 从cin中读取最多size个字节,并保存在首地址为sink的字符数组中。读取过程直到遇到delimiter或文件终止结束。如果遇到delimiter结束,则将其保留delimiter中,不读取出来。一个类似的函数是cin.getline(sink,size,delimiter) 两个方法的区别在于getline会读取delimiter并丢弃。

小结

一般情况下我们采用格式化IO不容易出错,尽量不采用未格式化IO。格式化IO提供了包括整型,浮点型,布尔型等类型的输出控制,还有通用的数据对齐,输出补白等常用功能。对于日常使用来说,这已经足够了。

猜你喜欢

转载自blog.csdn.net/wutao1530663/article/details/69124827