《白话C++》第10章 Page52 10.3.3 字符串格式化

10.3.3字符串格式化

先看一段代码:

#include <iomanip>

printf("\"%d, %4d, %04d\"\n", 11, 12, 13);

cout << '\"' << 11 << "," << setw(4)
    << setw(4) << 12 << "," << setw(4)
    << setfill('0') << 13 << '\n' << endl;

C++标准库的字符串格式化输出控制符,很不容易记忆。并且有的持续有效,有的单次有效。

可以上cppreference.comcplusplus.com查询,前者文档更佳,后者有不少好例子。

C语言的printf,又有类型不安全的问题。

boost::format提供了两全其美的解决方案:

#include <iostream>
#include <boost/format.hpp>

using namespace std;

void test1()
{
    cout << boost::format("I'm %s. I'm %d.") % "Tom" %10 << endl;
}

用法是: 先构造出一个boost::format对象,构造时传入一个“格式符控制串”, 然后用%操作符接收实际的参数 

“格式符控制串”,采用和printf基本一致的控制符表示法,比如s%表示这里需要一个字符串,d%表示需要一个整数。

1.类型指示符

格式化类型指示符如表10-2所列。

表10-2 格式化指示符表
类型指示符含义备注
%c一个字符char
%d一个整数digit
%u一个无符号整数unsigned
%f一个浮点数float,double
%e采用科学计数法的浮点数
%g自动选择 %f 和 %e选择比较短的表达法
%o以八进制显示给定的整数oct
%x以十六进制显示给定的整数hex,如果是%X,则字母大写
%s字符串直接支持  std::string
%p指针(一个内存地址)point,十六进制显示,如果确实是给一个变量的地址,则自动加上0x前缀
%%输出一个百分号

2.常见格式控制符

宽度控制,在类型指示符前面加一个正整数,表示输出宽度,比如:

 cout << boost::format("% 10s, % 4d") % "Tom" %123 << endl;

输出结果Tom前面将补充7个空格,123数字前面补充1个空格。如果在宽度指示符前面再加一个0,则不足位补充数字0,而不是空格:

cout << boost::format("% 010s, % 04d") % "Tom" %123 << endl;

也可以控制数字的精度:

 cout << boost::format("%8.3f, %3.2f") % 100.2 % 1234.567 << endl;

输出 100.200,1234.57

“%w.p”中,w表示输出总长度,浮点数包含小数点占1位,实际长度不足则如前述补位,实际长度超过,则取实长。p表示精度的表达长度,例子中100.2被输出为100.200,因为精度被指示为最少3为,实际精度不足自动补0,实际精度超过则以“四舍五入”原则截断!

3.简捷输出

为了快速组装不同数据成为一个字符串,boost也支持用户向C#语言学习,不需要指定类型:

cout << boost::format("%1% %2% %3% %1%") % "Hello" % 3 % 29 << endl;

“%N%”表示这里要替换为后面第N个参数,N从1开始(而不是0)。上一行输出代码的输出内容是“Hello 3 29 Hello”,打了两次招呼,是因为格式串中出现了两次“%1%”。

4.构造format对象备用

boost::format是一个类,可以事先构建出一个对象,这对于要整齐划一地输出一批数据,有提高性能的效果:

char const* names [] =
{
    "Tom", "Mike", "Mary", "Bill", "Alexander", "Bob"
};

int ages[] = {10, 22, 20, 32, 60, 7};
#define COUNT (sizeof(ages)/sizeof(ages[0]))

boost::format fmt("% 10s ==> %2d");

for(size_t i = 0; i < COUNT; ++ i)
{
    /**< boost为format这个类,重载了%操作符 */
    cout << fmt %names[i] %ages[i] << endl;
}

 

这里可以看出,并不是C++为“取余操作符(%)”提供了新的功能,而是boost为format这个类,重载了(%)操作符。

5.format异常

boost::format只要认为当前输出不会出现严重问题(内存越界,指针错指)等,它就会尽量输出,实际输出不了,它还是会抛出异常的,以下是format操作可能抛出的常见异常:

(1)bad_format_string

(2)too_few_args

(3)too_many_args

(4)out_of_range

每个异常的名字都基本做到了自我解释,实际使用时可以统一以它们的共同基类boost::io::format_error来捕获。

#include <boost/format.hpp>
#include <boost/format/exceptions.hpp>

...

try
{
    boost::format(...)...;
}
catch(boost::io::format_error const& e)
{
        cout << e.what() << endl;
}

6.更高级用法

boost::format还有一些更高级的用法,比如定制宽度补充字符,绑定输入参数等,需自学

最后,如果要处理wstring的格式化,需要采用对应的wformat类。

  • 20
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值