Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to convert TCHAR type to standard ISO C++ string?

905 views
Skip to first unread message

David F

unread,
Feb 27, 2006, 7:56:47 PM2/27/06
to
I am using VS2005.
When compiling:
TCHAR s;
......................
Then a routine from MS that sets s properly (w/o me
understanding one term there...-- its full of MS' macros) .
Now, if I compile it with the additional lines:

wsprintf((LPSTR)s, " %s",lpMsgBuf);
printf("Error: %s \n",s);

every thing is fine. If I compile instead with the printf()
with the line:
cout << s ;
it compiles w/o even a warning but during runtime it
spits a single hexadecimal number instead of a proper
string of about 40 characters as the printf() does.

So how to convert the proprietary TCHAR type string to a
standard C++ string, so it can be used in ISO standard C/C++?
Notes:
1. I don't use "Managed C++".
2. The suggested solutions in VS's help are not so helpfull - they
only add more none understood proprietary stuff.
3. The first two lines in my code are:
#include "stdafx.h"
#undef UNICODE

I don't know if the #undef statement is involved in the problem
but I must have it in order for the MS routine to work.

Thanks,
David
----------------------------------------------------------------
Bjarne Stroustrup: "Almost every macro demonstrate a flaw in
The programming language, in the program or in the programmer.".
TC++PL, 3rd Ed., p. 160.


Dr Pizza

unread,
Feb 27, 2006, 8:38:14 PM2/27/06
to
David F wrote:

Well, you do it by actually following MS's instructions instead of
ignoring them. Either use TCHAR routines consistently, or not at all.
Either convention is fine, but mixing them is not.

So, either do something like this:
TCHAR* s = _T("My String");
_tprintf(_T("Error: %s"), s);
typedef std::basic_string<TCHAR> tstring;
tstring str = s;
#ifdef UNICODE
#define tcout std::wcout
#else
#define tcout std::cout
#endif
tcout << _T("Error: ") << str << std::endl;

Or like this:
wchar_t* s = L"My String";
wprintf(L"Error: %s", s);
std::wstring str = s;
std::wcout << L"Error: " << str << std::endl;

Or, if you don't have UNICODE defined (it's the default in VC++ 2005
IIRC, as well it should be, because this is the 21st century for crying
out loud):

char* s = "My String";
printf("Error: %s", s);
std::string str = s;
std::cout << "Error: " << str << std::endl;

If you try to print a char* with wcout or a wchar_t* with cout, the
overload that gets called is the void* (because they have no overload
for the "opposite" string width), and the void* overload just prints
out the pointer's value in hex. This is why you see a hexadecimal
number instead of a string.

Mark Randall

unread,
Feb 28, 2006, 1:10:54 AM2/28/06
to
TCHAR *is* an ISO, the difference is it changes dependant on what _UNICODE
and UNICODE defines you have.

In essence it changes between std::string or std::wstring depending upon the
above values. You need to unset both _UNICODE and UNICODE to ensure all
around ASCIIness, or create your own typedef to do the same.

- MR

--
- Mark Randall
http://www.temporal-solutions.co.uk

"We're Systems and Networks..."
"It's our job to know..."
"David F" <David...@earthlink.net> wrote in message
news:jdNMf.3935$VI6....@newsread1.news.pas.earthlink.net...

Eugene Gershnik

unread,
Feb 28, 2006, 2:58:48 PM2/28/06
to
Dr Pizza wrote:
> #ifdef UNICODE
> #define tcout std::wcout
> #else
> #define tcout std::cout
> #endif

I prefer

namespace std
{
#if defined(_UNICODE) || defined(UNICODE)
wostream & tcout = wcout;
#else
ostream & tcout = cout;
#endif
};


--
Eugene
http://www.gershnik.com


Dr Pizza

unread,
Feb 28, 2006, 5:57:44 PM2/28/06
to
Eugene Gershnik wrote:

> Dr Pizza wrote:
> > #ifdef UNICODE
> > #define tcout std::wcout
> > #else
> > #define tcout std::cout
> > #endif
>
> I prefer
>
> namespace std
> {
> #if defined(_UNICODE) || defined(UNICODE)
> wostream & tcout = wcout;
> #else
> ostream & tcout = cout;
> #endif
> };

I didn't think re-opening std was an acceptable thing to do, though the
principle (of using references instead of #defines) is certainly sound
enough. I mostly just wanted something I could stick inline.

Eugene Gershnik

unread,
Feb 28, 2006, 8:08:28 PM2/28/06
to
Dr Pizza wrote:

> Eugene Gershnik wrote:
>
>
> I didn't think re-opening std was an acceptable thing to do,

Technically yes but I don't think there is a single compiler that is or ever
will going to complain.
I usually want exactly the same semantics as cout/wcout without using
macros. This is AFAIK impossible without reopening std.

--
Eugene
http://www.gershnik.com

Jerry Coffin

unread,
Feb 28, 2006, 9:49:45 PM2/28/06
to
In article <xn0ej14c6...@msnews.microsoft.com>,
DrP...@newsgroups.nospam says...

[ ... ]

> I didn't think re-opening std was an acceptable thing to do, though the
> principle (of using references instead of #defines) is certainly sound
> enough. I mostly just wanted something I could stick inline.

Reopening std is allowed. For example, if you define a
type, you can add a specialization for your type into
namespace standard -- though it still has to meet the
requirements on the original template or you undefined
results.

I'm pretty sure what was done in this case doesn't fall
within what's allowed though.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Tim Roberts

unread,
Mar 1, 2006, 2:29:14 AM3/1/06
to
"Mark Randall" <mark[__OKTHISISFAKE_]y...@REMOVETHISgoogle.ANDTHIScom> wrote:
>
>TCHAR *is* an ISO, the difference is it changes dependant on what _UNICODE
>and UNICODE defines you have.

No, it's not. It is purely a Microsoft invention, as are the _UNICODE and
UNICODE defines.

Handy, yes. Part of the ISO standard, no.
--
- Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Igor Tandetnik

unread,
Mar 1, 2006, 8:43:36 AM3/1/06
to
"Tim Roberts" <ti...@probo.com> wrote in message
news:v1ja02dh1mduqj5lp...@4ax.com

> "Mark Randall" <mark[__OKTHISISFAKE_]y...@REMOVETHISgoogle.ANDTHIScom>
> wrote:
>>
>> TCHAR *is* an ISO, the difference is it changes dependant on what
>> _UNICODE and UNICODE defines you have.
>
> No, it's not. It is purely a Microsoft invention, as are the
> _UNICODE and UNICODE defines.
>
> Handy, yes. Part of the ISO standard, no.

Well, Mark could perhaps have chosen a better wording, but his point is
valid. He responded to this question:

> So how to convert the proprietary TCHAR type string to a
> standard C++ string, so it can be used in ISO standard C/C++?

which kind of implies that TCHAR is dark magic and a program using it is
automatically not standard C++ compliant. Which is not the case of
course - while TCHAR is not specifically standardized, it is defined in
terms of ISO standard constructs.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


0 new messages