有关 boost::lexical_cast 的问题

freeshoot 2008-04-06 11:49:07
众所周知,使用:
sprintf(buf, "%02d", i) 或 sprintf(buf, "%.2f", j)
很容易实现int或float等型别向string转换,并带格式化功能。

而最近学习使用boost:
float f = 1.23456;
std::string str = boost::lexical_cast<std::string>(f);
感觉格式化输出字符串,好像做不到。

请问各位有经验的朋友,boost格式化输出字符串有何好办法。
如实现: sprintf(buf, "%.2f", 1.23456f)
...全文
193 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Chappell 2008-04-07
  • 打赏
  • 举报
回复
路过
sheenl 2008-04-07
  • 打赏
  • 举报
回复
lexical_cast内部就是一个stringstream做类型转换, 没有什么好办法来变幻格式, 很笨的东西, 我觉得这个东西意思不大, 还不如自己用stringstream换来的方便. 还可以自己控制一些格式.
taodm 2008-04-07
  • 打赏
  • 举报
回复
你还是用ostringstream吧。
  • 打赏
  • 举报
回复
lexical_cast 只是类型转化
用Boost::Format合适
CathySun118 2008-04-07
  • 打赏
  • 举报
回复
Boost.Format 学习了
Supper_Jerry 2008-04-07
  • 打赏
  • 举报
回复
std::string是个很不错的东东,但实际使用时基本在每个程序里都会遇到不愉快的事情:格式化字符串。我甚至由于这个原因在代码里引入平台有关的MFC,ATL等本来不需要在项目中使用的一些重量级的框架,就为了能轻松的做格式化字符串 :-) 。曾尝试过将ATL::CString的format函数提取出来使用,但ATL::CString的底层调用了windows独有函数,无法跨越平台。当然,现在有了boost::format,我们不用再担心了。boost::format重载了'%'操作符,通过多次调用'%'操作符就能将参数非常方便格式化成字符串,并实现了ATL::CString和C#中的string两者的格式化字符串功能。除了语法刚开始感觉到怪异,功能足以让人感觉到兴奋! 




一、boost::format工作的方式

基本的语法,boost::format( format-string ) % arg1 % arg2 % ... % argN

下面的例子说明boost::format简单的工作方式



// 方式一
cout << boost::format("%s") % "输出内容" << endl;

// 方式二
std::string s;
s = str( boost::format("%s") % "输出内容" );
cout << s << endl;

// 方式三
boost::format formater("%s");
formater % "输出内容";
std::string s = formater.str();
cout << s << endl;

// 方式四
cout << boost::format("%1%") % boost::io::group(hex, showbase, 40) << endl;




二、boost::format实际使用的实例

格式化语法: [ N$ ] [ flags ] [ width ] [ . precision ] type-char



// ATL::CString风格
cout << boost::format("\n\n%s"
"%1t 十进制 = [%d]\n"
"%1t 格式化的十进制 = [%5d]\n"
"%1t 格式化十进制,前补'0' = [%05d]\n"
"%1t 十六进制 = [%x]\n"
"%1t 八进制 = [%o]\n"
"%1t 浮点 = [%f]\n"
"%1t 格式化的浮点 = [%3.3f]\n"
"%1t 科学计数 = [%e]\n"
) % "example :\n" % 15 % 15 % 15 % 15 % 15 % 15.01 % 15.01 % 15.01 << endl;

// C#::string风格
cout << boost::format("%1%"
"%1t 十进制 = [%2$d]\n"
"%1t 格式化的十进制 = [%2$5d]\n"
"%1t 格式化十进制,前补'0' = [%2$05d]\n"
"%1t 十六进制 = [%2$x]\n"
"%1t 八进制 = [%2$o]\n"
"%1t 浮点 = [%3$f]\n"
"%1t 格式化的浮点 = [%3$3.3f]\n"
"%1t 科学计数 = [%3$e]\n"
) % "example :\n" % 15 % 15.01 << endl;


输出结果
/**//*
example :
十进制 = [15]
格式化的十进制 = [ 15]
格式化十进制,前补'0' = [00015]
十六进制 = [f]
八进制 = [17]
浮点 = [15.010000]
格式化的浮点 = [15.010]
科学计数 = [1.501000e+001]
*/


三、boost::format新的格式说明符

%{nt}
当n是正数时,插入n个绝对制表符
cout << boost::format("[%10t]") << endl;

%{nTX}
使用X做为填充字符代替当前流的填充字符(一般缺省是一个空格)
cout << boost::format("[%10T*]") << endl;


四、异常处理



一般写法:


try
{
cout << boost::format("%d%d") % 1 << endl;
}
catch(std::exception const & e)
{
cout << e.what() << endl;

// 输出内容:
// boost::too_few_args: format-string refered to more arguments than were passed
}


boost::format的文档中有选择处理异常的办法,不过个人感觉实用性可能不强,下面是文档中的例子



// boost::io::all_error_bits selects all errors
// boost::io::too_many_args_bit selects errors due to passing too many arguments.
// boost::io::too_few_args_bit selects errors due to asking for the srting result before all arguments are passed

boost::format my_fmt(const std::string & f_string)
{
using namespace boost::io;
format fmter(f_string);
fmter.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
return fmter;
}
cout << my_fmt(" %1% %2% \n") % 1 % 2 % 3 % 4 % 5;


五、还有其它一些功能,但暂时感觉派不上用处,就不去深究了。
Inhibitory 2008-04-07
  • 打赏
  • 举报
回复
Boost format其实就是将原来printf带参数的方法改成了用%操作符带参数,格式化表达式与printf非常像.
引用http://blog.csdn.net/kese/archive/2007/06/20/1659602.aspx
代码绝大部分来自boost自带的文档,我只是用来研究boost
format_1.cpp

#include <iostream>
#include <iomanip>
#include <cassert>

#include "boost/format.hpp"

// 2 custom namespaces, to bring in a few useful names :

namespace MyNS_ForOutput {
using std::cout; using std::cerr;
using std::string;
using std::endl; using std::flush;

using boost::format;
using boost::io::group;
}

namespace MyNS_Manips {
using std::setfill;
using std::setw;
using std::hex ;
using std::dec ;
// gcc-2.95 doesnt define the next ones
// using std::showbase ;
// using std::left ;
// using std::right ;
// using std::internal ;
}

int main(){
using namespace MyNS_ForOutput;
using namespace MyNS_Manips;

std::cout << format("%|1$1| %|2$3|") % "Hello" % 3 << std::endl;

// Reordering :
cout << format("%1% %2% %3% %2% %1% \n") % "o" % "oo" % "O"; // 'simple' style.
// prints "o oo O oo o \n"
cout << format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35; // Posix-Printf style


// No reordering :
cout << format("writing %s, x=%s : %d-th step \n") % "toto" % 40.23 % 50;
// prints "writing toto, x=40.23 : 50-th step \n"

cout << format("(x,y) = (%+5d,%+5d) \n") % -23 % 35;
cout << format("(x,y) = (%|+5|,%|+5|) \n") % -23 % 35;
cout << format("(x,y) = (%|1$+5|,%|2$+5|) \n") % -23 % 35;
// all those are the same, it prints "(x,y) = ( -23, +35) \n"



// Using manipulators, via 'group' :
cout << format("%2% %1% %2%\n") % 1 % group(setfill('X'), hex, setw(4), 16+3) ;
// prints "XX13 1 XX13\n"


// printf directives's type-flag can be used to pass formatting options :
cout << format("_%1$4d_ is : _%1$#4x_, _%1$#4o_, and _%1$s_ by default\n") % 18;
// prints "_ 18_ is : _0x12_, _ 022_, and _18_ by default\n"

// Taking the string value :
std::string s;
s= str( format(" %d %d ") % 11 % 22 );
assert( s == " 11 22 ");


// -----------------------------------------------
// %% prints '%'

cout << format("%%##%#x ") % 20 << endl;
// prints "%##0x14 "


// -----------------------------------------------
// Enforcing the right number of arguments

// Too much arguments will throw an exception when feeding the unwanted argument :
try {
format(" %1% %1% ") % 101 % 102;
// the format-string refers to ONE argument, twice. not 2 arguments.
// thus giving 2 arguments is an error
}
catch (boost::io::too_many_args& exc) {
cerr << exc.what() << "\n\t\t***Dont worry, that was planned\n";
}


// Too few arguments when requesting the result will also throw an exception :
try {
cerr << format(" %|3$| ") % 101;
// even if %1$ and %2$ are not used, you should have given 3 arguments
}
catch (boost::io::too_few_args& exc) {
cerr << exc.what() << "\n\t\t***Dont worry, that was planned\n";
}


cerr << "\n\nEverything went OK, exiting. \n";
system("pause");
return 0;
}


format 比较复杂,在这里展示了format的三种用法,以及两种错误的用法
其实format的用法,如果要是用简单一点的方法理解的话就不复杂了
format其实就是将原来printf带参数的方法改成了用%操作符带参数,格式化表达式与printf非常像,
例如都是使用%来带格式化表达式,不同的时%后的东西要比printf好用,其实更好理解一些
星羽 2008-04-07
  • 打赏
  • 举报
回复
Boost.Format

??

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧