• boost之字符串--lexical_cast


    函数由来

    顾名思义,lexical_cast库进行“字面值”的转换,类似c中的atoi()函数,可以进行字符串与整数/浮点数之间的字面转换。

    #include<boost/lexical_cast.hpp>

    using namespace boost;

    我们都很熟悉c语言中的atoi()、atof()系列函数,它们可以把字符串转换成数值,但这种转换是不对称的,不存在如 itoa ()这样的反向转换°,要想把数值转换为字符串,只能使用不安全的printf ()

    标准形式:

    转化成 数字和字符串

    template

    inline Target  lexical_cast(const Source &arg);

    //转化c字符

    template

    inline Targe lexical_cast(const char* chars,std::size_t count);

    函数用法:

    1. int x =lexical_cast<int>("100");//string->int
    2. long y =lexical_cast<long>("2000");//string->长整数
    3. float pai =lexical_cast<float>("3.13159e5");
    4. double e =lexical_cast<double>("2,71828");
    5. double r =lexical_cast<double>("1.414,x",5);
    6. std::cout<" "<" "<" "<<
    7. e<<" "<" ";
    8. std::string str =lexical_cast(456);
    9. std::cout<
    10. std::cout<<lexical_cast(0.618)<
    11. std::cout<<lexical_cast(0x10)<
    12. //
    13. 100 2000 3141592.71828 1.414
    14. 456
    15. 0.61799999999999999
    16. 16

    错误处理:

    1. try{
    2. int x =lexical_cast<int>('100');//string->int
    3. long y =lexical_cast<long>('2000');//string->长整数
    4. float pai =lexical_cast<float>("3.13159e5");
    5. double e =lexical_cast<double>("2,71828");
    6. double r =lexical_cast<double>("1.414,x",5);
    7. }
    8. catch(bad_lexical_cast&e)
    9. {
    10. std::cout<<"error: "<what()<
    11. }

    lexical_cast在名字空间boost : : conversion提供try lexical convert ()函数,可以避免抛出异常,它以bool返回值表示是否转换成功。函数的声明是:

    1. int x;
    2. assert(!conversion::try_lexical_convert("0x100",5))

    验证数字字符串的合法性

    1. assert( !num_valid<double> ("3.14"));
    2. assert( !num_valid<int> ( "3.14"));
    3. assert (!num_valid<int>("65535"));

    应用于自定义类

    如果我们想要将lexcical_cast应用于自定义的类,把类转换为可理解的字符串描述(类似于Java语言中的object.tostring ()用法),只需要满足lexcical_cast的要求即可。准确地说,需要实现流输出操作符operator<<。

    1. class dome_class
    2. {
    3. friend std::ostream& operator<<(std::ostream&os,const demo_class&x)
    4. {
    5. os<<"demo_class's Name";
    6. return os;
    7. }
    8. }
    9. std::cout<<lexical_cast(demo_calss())<

    这段代码具有通用性,值得把它提取为一个模板类。我们可以仿造boost.operator库,定义一个模板类outable,以简化流输出操作符<<的重载。注意,这里没有使用基类链技术,不能用于operator的基类串联,但可以很容易添加这个功能:

    1. template<typename T>
    2. struct outable
    3. {
    4. friend std::ostream&operator<<(std::ostream os,const T& x)
    5. {
    6. os<<typeid(T).name();// 使用typeid操作符输出类型名字
    7. return os;
    8. }
    9. }

    format

    C++输入/输出流也不是完美无瑕的,精确输出的格式控制要写大量的操控函数,而且会改变流的状态,用完后还需要及时恢复,有时候会显得十分烦琐。因此,还是有很多程序员怀念c语言中经典的printf(),虽然它缺乏类型安全检查,还有其他的一些缺点,但它语法简单高效,并且被广泛地接受和使用,影响深远。

    format组件位于名字空间boost,需要包含头文件hpp>,即;

    #include

    using namespace boost;

    用法:

    1. std::cout<"%s:=%d+%d=%d\n")%"sum"%1%2%(1+2);
    2. format fmt("(%1%+%2%)*%2%=%3%\n");
    3. fmt %2%5;
    4. fmt %((2+5)*5);
    5. std::cout<str();

    第一条format语句的等价printf ()调用是

    printf ( "%s : %d+%d=%d\n" , " sum", 1,2,(1+2));

    format ( ...) << a<< b<

    操作符%把参数逐个地“喂”给format对象,完成对参数的格式化。

    后面的三行语句演示了format 的另一种用法,

    预先创建一个format格式化对象,它可以被后面的代码多次用于格式化操作。format对象仍然用操作符%来接受被格式化的参数,可以分多次输入(不必一次给全),但参数的数量必须满足格式化字符串的要求。最后,使用format对象的str ()成员函数获得已格式好的字符串向cout流输出。

    第二个format用了略不同于printf()的格式化语法:"(%1%+%2%)* %2%= %3% \n",有点类似c#语言,%N%可以指示参数的位置,减少参数输入的工作——这是对printf()语法的一个改讲,

    第二个format对象的等价printf ()调用是

    printf ("(%d + %d)* %d = %d\n" ,2,5,5,(2+5)*5);

    格式化语法:

    %05d:  输出宽度为5的整数,不足位用0填充;

    %-8.3f :输出左对齐,总宽度为8,小数位3位的浮点数;

    % 10s:输出10位的字符串,不足位用空格填充;

    %05x :输出宽度为5的大写十六进制整数,不足位用0填充。

    % lspecl     :与printf格式选项功能相同,但两边增加了竖线分隔,可以更好地区分格式化选项与普通字符;

    %N% :标记第N个参数,相当于占位符,不带任何其他的格式化选项。

    format fmt("%|05d|\n%|-8.3f|\n%l10s|\n%|05X|\n ")

  • 相关阅读:
    @Transient注解
    [GUET-CTF2019]zips
    【算法刷题】—7.25 Dijkstra 算法应用
    深入React源码揭开渲染更新流程的面纱
    RPC服务与HTTP服务的区别是什么
    SSH在桌面会话启动应用程序
    算法竞赛进阶指南 基本算法 0x03 前缀和与差分
    010-JAVA一维数组与多维数组
    MATLAB初学者入门(3)—— 优化模型求解
    有哨兵位双向循环链表
  • 原文地址:https://blog.csdn.net/qq_62309585/article/details/126891074