【STL】警惕istringstream数据格式化误区

【导语】

   istringstream支持泛型,可以将字符串格式化特定类型的数据,给开发者的使用带来了很大的方便性。但是,如果使用不当,会带来严重BUG。

【背景】

   上周做商旅频道,SVR通过向DB查询数据,供前端展示。但是发现一个让人很困惑的问题:当DB中的字符类型数据以★开头时,前端只会展示★,其后内容根本不展示。

【分析】

   这是什么原因呢?起初怀疑MySQL在碰到火星文时会出现数据截断问题,但通过MySQL的命令行工具查看,数据都能正确展示出来,问题肯定不出在MySQL。问题是什么?经过日志跟踪,法线问题就出在了istringstream格式化数据方面!

   为减少重复代码,自我封装的数据库操作类使用了泛型编程,通过istringstream来格式化数据:

 template<class T>
    bool Fetch( uint32_t dwFieldIndex,  T &data)
    {   
        const char* ptr = NULL;
        if (!_FetchPtr(dwFieldIndex, ptr) || !ptr)
        {   
            assert(ptr != NULL);
            return false;
        }   
         
        std::istringstream buffer;
        buffer.str(ptr);
        buffer>>data;
        return true;
    }  

问题就出在istringstream上面。当data的类型为string时,istringstream将数据格式化为字符串时,会像cin一样,遇到空白符就停止

回过头看我的数据时,确实发现每个★后面都跟这一个空格!问题确认了!确认这一个问题,整整花了我一个上午时间。

【其他问题】

    istringstream同样在其他方面存在陷阱,必须提前知道这些知识,才能应对自如。

    1. 在格式化uint8_t方面存在陷阱。请思考下面这段代码的输出结果是什么?

#include <stdint.h>
#include <sstream>
#include <string>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    const char* ptr = "1";
    istringstream iss(ptr);
    
    uint8_t ucVal;
    iss >> ucVal;
    cout << "ptr = " << ptr << "; ucVal = " << (int)ucVal << endl;

    return 0;
}

ptr = 1; ucVal = 49

ucVal是49,不是1!是不是出乎你的意料?要让ucVal输出1,那么ucVal的类型必须是int/uint32_t/long之类的。同样, ucVal的类型是int8_t,也会存在和uin8_t相同的问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值