【问题标题】:string to boost::uint64_t fails with lexical_cast and stringsteamstring to boost::uint64_t 因 lexical_cast 和 stringsteam 而失败
【发布时间】:2013-03-18 14:09:36
【问题描述】:

我正在尝试将字符串转换为boost::uint64_tpvalue 的内容是12345678901234567890。我现在使用的代码是:

void setAttribute(EnumAttrTyoe pname, const void *pvalue) {
    if (pname == SESS_ID) {
        const char *raw_sess_id = reinterpret_cast<const char*>(pvalue);
        std::string str_sess_id(raw_sess_id);
        std::cout << "Trying to open session id: '" << str_sess_id << "'\n";
        m_session_id = boost::lexical_cast<unsigned long long>(str_sess_id);
    }
}

这会引发异常,并显示消息“错误的词法转换:源类型值无法解释为目标”。如果改为使用此代码:

void setAttribute(EnumAttrTyoe pname, const void *pvalue) {
    if (pname == SESS_ID) {
        const char *raw_sess_id = reinterpret_cast<const char*>(pvalue);
        std::string str_sess_id(raw_sess_id);
        std::stringstream ss;
        ss << raw_sess_id;
        ss >> m_session_id;
    }
}

它通过了,但m_session_id 的值为0。我还没有检查ss 的标志,但我不需要很聪明就知道它失败了。有什么想法现在该怎么做?

更新没有 C++11,因为我不能使用它,而且我的编译器是 VC++ 2008,boost 版本 1.43.0。

【问题讨论】:

  • 您使用的是什么编译器和 boost 版本?
  • boost 为 1.43.0,编译器 MS VC++ 2008

标签: c++ boost 64-bit


【解决方案1】:

此代码适用于我:

#include <sstream>
#include <cstdint>
#include <iostream>

int main()
{
   std::stringstream ss;
   ss << "12345678901234567890";

   std::uint64_t n = 0;
   ss >> n;

   std::cout << n << "\n";
}

输出到http://liveworkspace.org:

标准输出: 12345678901234567890

【讨论】:

    【解决方案2】:

    我认为你输入的 C 风格字符串不是你想象的那样。 boost::lexical_cast 的这种用法在 boost 1.42 上适用于我:

    #include <iostream>
    #include <boost/lexical_cast.hpp>
    #include <boost/cstdint.hpp>
    
    int main() {
       std::string s = "12345678901234567890";
       boost::uint64_t i = boost::lexical_cast<boost::uint64_t>(s);
       std::cout << i << '\n';
       return 0;
    }
    

    我的猜测是您的输入不是以零结尾的,具有您不期望的后缀,或者具有像 UTF16 这样的替代编码。或者它甚至不是一个字符串。

    【讨论】:

    • 我也是这样,(事实上这就是我用它构建字符串的原因),无论如何,我尝试转储字符串,如 std::cout
    • 我不会只相信字符串的打印,因为可能嵌入了非打印字符。我会在你的函数中设置一个断点并检查pvalue 的内存。它应该只包含从 0x30 到 0x39 直到终止 0x00 的十六进制值。或者,您可以遍历字符串并使用isdigit() 进行测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多