【问题标题】:Access violation when converting from uint32_t to wchar_t and storing in wstring从 uint32_t 转换为 wchar_t 并存储在 wstring 中时访问冲突
【发布时间】:2020-03-21 02:15:33
【问题描述】:

这可能是一个简单的问题,但我在 DirectXTDK 中有一个 uint32_t 中的值。我想通过将它与 wchar_t 连接来显示它。

这是我目前所拥有的 -

char buffer[1];
wchar_t* ws1 = (wchar_t *)itoa(m_timer.GetFramesPerSecond(), buffer, 10), * ws2 = L" FPS";
std::wstring s(ws1);
s += std::wstring(ws2);
const wchar_t* fps = s.c_str();

// Draw Text to the screen
m_sprites->Begin();
    m_font->DrawString(m_sprites.get(), L"DirectX Museum Scene", XMFLOAT2(10, 10), Colors::Yellow);
    m_font->DrawString(m_sprites.get(), fps, XMFLOAT2(8, 30), Colors::Yellow);
m_sprites->End();

当尝试显示默认字体无法处理的垃圾字符时,会出现问题。如果没有 itoa,执行将在 std::wstring s(ws1) 处抛出异常。

如何有效地将 uint32_t 转换为 wchar_t * 以正确显示 FPS?谢谢!

【问题讨论】:

  • 似乎您没有为itoa 转换分配足够大的缓冲区。您至少需要 2 个缓冲区大小,一个用于 FPS(如果它只有一个十进制数字),一个用于终止空字符。但更现实的是,找出你的最大 FPS 是多少,并分配足够的空间来容纳那么多数字 + 1。更好的是,在缓冲区中分配 33 个chars 来处理长达 32 位的数字。
  • (wchar_t *)itoa -- 移除演员表。你得到什么编译器错误?仔细阅读这个错误——不要通过 C 风格的转换来掩盖它。对于字符串或字符串类型,您应该很少(如果有的话)进行这样的转换。要么使用正确的字符串类型,这样你就不需要强制转换,要么找到使用你正在使用的字符串类型的正确函数。
  • @John 您不需要 33 个字符(32 个十进制数字)来处理具有 32 位表示的数字。最大可能是 4,294,967,295,只有 10 位。
  • @LightnessRaceswithMonica 谢谢你,你是对的。我阅读了itoa 的参考页,并浏览了建议使用该尺寸为 radix=2 的部分。我的脑袋放屁。
  • @John:呵呵呵呵:)

标签: c++ directx wchar-t uint32-t


【解决方案1】:

itoa 产生一个 ASCII 字符串,而不是一个宽字符串。

您必须进行 C 风格的强制转换才能强制更改指针类型,这是一个危险信号;您永远不必这样做,而且当您这样做时,结果通常是错误的。类型系统可以为您提供帮助!

我还担心您选择的缓冲区大小;你知道每秒帧数只有一位吗?空终止符的空间在哪里?

我想你想要_itow。但是,要解决缓冲区问题,_itow_s 会更好。

更好的是,完全跳过遗留的东西,给自己一个漂亮的std::to_wstring。 ?

【讨论】:

    【解决方案2】:

    @Lightness Races with Monica 让我朝着正确的方向前进 :)

    转换为 wstring 并按预期工作

    //char buffer[11]; // 32 bits, 10 characters + 1 for terminating null character
        std::wstring ws1 = std::to_wstring(m_timer.GetFramesPerSecond());
        std::wstring ws2 = L" FPS";
        std::wstring s(ws1);
        s += std::wstring(ws2);
        const wchar_t* fps = s.c_str();
    
        // Draw Text to the screen
        m_sprites->Begin();
            m_font->DrawString(m_sprites.get(), L"DirectX Museum Scene", XMFLOAT2(10, 10), Colors::Yellow);
            m_font->DrawString(m_sprites.get(), fps, XMFLOAT2(8, 30), Colors::Yellow);
        m_sprites->End();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-13
      • 2012-05-22
      • 1970-01-01
      • 2015-09-16
      • 2017-12-12
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多