C++: LPWSTR prints as an address in cout
Asked Answered
P

1

10

I have a variable of type LPTSTR, which I print to std::cout with <<. In an ANSI system (don't know exactly where it is determined) it worked fine, it printed the string. Now in a Unicode system I get a hex address instead of the string. So, why does LPSTR (to which LPTSTR is resolved if UNICODE is not defined) act differently from LPWSTR (... if UNICODE is defined) and how do I print the string pointed by the latter one?

Patmos answered 3/5, 2011 at 17:35 Comment(0)
P
16

For Unicode strings you want wcout.

You may be seeing hex because the ANSI/ASCII output stream doesn't know how to handle Unicode characters.

LPTSTR and LPWSTR are actually C-isms inherited from the C Windows API days. For C++ I would strongly encourage you to use std::string and/or std::wstring instead.

If you need to roll your own macro, you'll want something like:

#ifdef _UNICODE
std::wostream& COUT = std::wcout;
#else
std::ostream& COUT = std::cout;
#endif
Philippeville answered 3/5, 2011 at 17:38 Comment(7)
Oh, thanks. And is there a standart macros that resolves to cout or wcout automatically?Patmos
And about using std::string - unfortunately, LPTSTRs are used in WinAPI functions so I have to use them. And to avoid unnesessary conversions I have to use them all along.Patmos
You can use the .c_str() method when you want a C-style null-terminated string to pass to the Windows API.Philippeville
Concerning the standard macro: I'm not sure (I'm mostly doing C# these days). If I remember correctly I had to roll my own but that was a few years ago. It shouldn't be too difficult. See edited response.Philippeville
And what about strings returned from WinAPI functions? I'll have to create new string objects for every one to use it. And, most importantly, such strings are often members of WinAPI structures... Specifically, I have an array of such structures returned from a function. Converting strings from them to std::string is a no way.Patmos
Yes, if you're accessing the Windows API at a low level those things can be painful. It depends on what kind of software you're developing. If you're writing device drivers, you probably need to stick with the low-level API. If, however, you're writing line-of-business applications, you will probably find it worth your while to "wrap" the low-level functionality. For an example see the managed wrappers for the WiFi API at <managedwifi.codeplex.com>.Philippeville
I'd use std::wostream& COUT = std::wcout; and std::wostream& COUT = std::cout; instead of #define COUT wcout and #define COUT coutIneducation

© 2022 - 2024 — McMap. All rights reserved.