2

I'm sorry that this is quite a recycled problem, but most of the help on here hasn't helped. My problem is that I want to be able to display integers in my Win 32 application but obviously they need to be in a certain format to be printed (LPCWSTR I believe). So I tried this:

LPCWSTR intToString(int i){
    TCHAR buf[32];
    _itow_s(i, buf, 10);
    return buf;
}

But it when I printed it using

TextOut(hdcBuffer, 30, 40, intToString(xValue), 32);

It printed lots of random characters to the screen, much like trying to open a file in notepad when it really isn't meant to be opened there. (so with random squares, lines, ampersands etc.) I've tried things like sprintf() and a few other things that I can't remember. Please don't suggest downloading new libraries or anything because I don't want to do that, particularly, unless it is the only way.

Again, sorry for such repetitivity, but the solutions on other pages just don't seem to work. I'm using Visual Studio 2012 on a Windows 7 computer. If you require any more info please say so, I'll co-operate to the best of my ability.

Thank you :)

  • How about `std::to_wstring` and `c_str()`? – chris Jul 06 '13 at 20:50
  • To expand upon what chris said, he's how you can convert int to string using c++ standard library: [here](https://ideone.com/WtzchP) – Borgleader Jul 06 '13 at 20:52
  • May I ask how I would implement this? :) Using the TextOut fuction with this method throws up a few problems, but it seems to be working. I don't know how to access the console within a Win32 app to check though, sorry. – Bradley Hodgkins Jul 06 '13 at 21:24
  • Use OutputDebugString(LPCTSTR) to output to Visual Studio Output pane. And don't mind temporarily using my solution, despite all the downvotes. Just keep in mind that it is only temporary, to get you going. – Tony Jul 06 '13 at 21:34

3 Answers3

3
#include <sstream>

template<typename U>
std::wstring towstring(const U& val)
{
    std::wstringstream ss;
    ss << val;
    return ss.str();
}

And later in code:

TextOut(hdcBuffer, 30, 40, towstring(xValue).c_str(), 32);
milleniumbug
  • 15,379
  • 3
  • 47
  • 71
  • That worked perfectly thank you :) Thank you to every one else who submitted an answer, I'm just too noob-ish to have made them work. Again, thank you :) I'm sorry that it was a duplicate, I didn't even realise I was referencing a local variable, I honestly thought it was something more complex. – Bradley Hodgkins Jul 07 '13 at 06:07
0

The function intToString it returning a pointer to a local variable. Once the function returns buf no longer exists and attempt to reference the memory it once occupied results in undefined behavior. This means that sometimes it may work and other times it may not but nothing is guaranteed.

You can get this to work by passing the buffer to intToString and returning a pointer to it.

template<int size>
const wchar_t* intToString(int i, wchar_t (&buf)[size])
{
    _itow_s<size>(i, buf, 10);
    return buf;
}

TCHAR buf[20];
TextOut(hdcBuffer, 30, 40, intToString(xValue, buf), 32);
Captain Obvlious
  • 19,754
  • 5
  • 44
  • 74
  • Hey, thanks for the reply, this makes a lot of sense. I'm trying to implement this now, but I'm not entirely sure how to make the prototype for this function, I put the template and the function at the bottom of my page, but I'll move it above the main chunk for a while if this helps. Thanks again! – Bradley Hodgkins Jul 06 '13 at 21:13
-6

Your buffer is temporary variable allocated on stack that will be gone when intToString function returns.

Try:

LPCWSTR intToString(int i){
    static TCHAR buf[32];
    _itow_s(i, buf, 10);
    return buf;
}
Tony
  • 1,566
  • 2
  • 15
  • 27
  • If you make the variable static and call the function multiple times your pointers will all point to the same one and the therefore will all have the value created by the last invocation. [See here](https://ideone.com/kCjyLg), the x variable changes value for each call of the function but when you print the variables the output is the same for both. – Borgleader Jul 06 '13 at 21:02
  • True, intended only as a quick fix for OP, assuming he is not caching returned pointers. – Tony Jul 06 '13 at 21:09
  • As long as the use case is: `TextOut(hdcBuffer, 30, 40, intToString(xValue), 32);` it will work. I'm afraid that anything else is just confusing OP at this time. – Tony Jul 06 '13 at 21:23
  • 1
    Doesn't matter, you're replacing one bug by another arguably subtler bug. – Borgleader Jul 06 '13 at 21:25
  • 2
    Note: this solution suffers from multithreading issues (this can be solved somehow), reentrancy issues, inability to store returned string (requiring caller to copy it), and fails when calling multiple times (this can be solved somehow), and generally, while acceptable in C, it's really bad in C++. – milleniumbug Jul 06 '13 at 21:38
  • Note: this solution is intended to be used only in limited use case presented by the OP, where he is outputting a string on GUI thread via TextOut function, in order to get him going. All the above warnings are valid. – Tony Jul 06 '13 at 21:57