1

This might be a simple question, but I have a value in DirectXTDK that is in uint32_t. I would like to display this by concatenating it with a wchar_t.

This is what I have so far -

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();

The issue occurs when displaying FPS as garbage characters are trying to be displayed that the default font cannot handle. Without itoa, the execution will throw an exception at std::wstring s(ws1).

How can I effectively convert uint32_t to wchar_t * to display FPS properly? Thanks!

firepro20
  • 63
  • 1
  • 8
  • Seems like you're not allocating a large enough buffer for the `itoa` conversion. You'll need at LEAST a buffer size of 2, one for the FPS (if it's only one decimal digit), and one for the terminating null character. But more realistically, find out what your maximum FPS is, and allocate enough space to hold that many digits + 1. Better yet, allocate 33 `char`s in the buffer to handle numbers up to 32 bits long. – JohnFilleau Nov 25 '19 at 18:14
  • 1
    `(wchar_t *)itoa` -- Remove the cast. What compiler error do you get? Read that error carefully -- don't cover it up by doing a C-style cast. With strings or string types, you should rarely, if ever, cast things like this. Either use the correct string types so that you don't need to cast, or find the correct functions that use the string types you're using. – PaulMcKenzie Nov 25 '19 at 18:14
  • 1
    @John You do not need 33 chars (32 decimal digits) to handle numbers with a representation of 32 bits. The largest possible is 4,294,967,295 which only has 10 digits. – Lightness Races in Orbit Nov 25 '19 at 18:15
  • @LightnessRaceswithMonica thank you, you're right. I read the reference page for `itoa` and skimmed over the part where that size was suggested for radix=2. Brain fart on my end. – JohnFilleau Nov 25 '19 at 18:20
  • @PaulMcKenzie Exception thrown at 0x00007FFC105D2E3C (ucrtbased.dll) in DirectXTKSimpleSample_2015.exe: 0xC0000005: Access violation reading location 0x0000000000000000. occurred when I change to wchar_t* ws1 = (wchar_t *)(m_timer.GetFramesPerSecond()) – firepro20 Nov 25 '19 at 18:40
  • @firepro20 That is a runtime error, not a compiler error. When you compile the code with those casts removed, what error does the compiler give you? Why did you cast? You basically told the compiler to "shut up, don't give me an error, I know what I'm doing", but of course, that isn't the case. Example: `wchar_t* ws1 = itoa(m_timer.GetFramesPerSecond(), buffer, 10)` -- I am sure the compiler would have told you that this was illegal. – PaulMcKenzie Nov 25 '19 at 18:44
  • @firepro20 You were instructed to remove the cast and read the resulting error, not remove the cast and the function call and other things too – Lightness Races in Orbit Nov 25 '19 at 18:51
  • @lightness got it working thanks! – firepro20 Nov 25 '19 at 19:52

2 Answers2

1

itoa produces an ASCII character string, not a wide string.

That you had to throw in a C-style cast to force a pointer type change is the red flag there; you should never have to do that and, when you do, the result is normally wrong. The type system is there to help you!

I'm also concerned by your choice of buffer size; do you know that there will only be one digit in the frames-per-second value? And where is the space for the null terminator?

I think you wanted _itow. But, to fix the buffer problem, _itow_s would be better.

Better still, skip the legacy stuff entirely and get yourself a nice std::to_wstring.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

@Lightness Races with Monica put me in the right direction :)

converted to wstring and works as expected

//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();
firepro20
  • 63
  • 1
  • 8