Is there a way to use std::cout with a LPTSTR?

This topic is 4419 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I'm trying to output a string to the console, where the string came from a function that returned a LPTSTR. So basically:
LPTSTR  burp = _T("Fffurrp!");
std::cout << (CHAR*)burp << endl;
This only outputs a single letter, 'F'. Anyone know how to get the whole string to print?

Share on other sites
Sounds like you're compiling in Unicode mode, where LPTSTR represents strings in UTF-16 format. The second byte of your data, then, is zero, and gets interpreted as the end of the string by std::cout. Try std::wcout instead:
LPTSTR burp = _T("Fffurrp!");std::wcout << burp << std::endl;

Share on other sites
Wahey that works.. but the 'w' functions only handle Unicode right? I've been using the 't' conversions and functions so it can handle ascii, unicode, or multibyte characters as well.

I can't find something like "tcout". With sprintf you have a _stprintf, which just uses sprintf for multibyte characters anyway. Just that cout I need.

Share on other sites
You'll need to define it yourself. The C++ Standard library components don't come with generic text mapping aliases.

Share on other sites
#ifdef UNICODEostream& tcout = wcout;#elseostream& tcout = cout;#endif

Should work (and without evil #define) :)

EDIT: Yes, it was the wrong way around before. Doh :)

[Edited by - Zahlman on January 4, 2006 4:28:16 PM]

Share on other sites
Ah, thank you. Should have thought of defining my own one sooner.
But now I'm curious about these new things mentioned... #define is evil? Actually I'm getting linker errors using the ostream& way.. using #define does get it to compile.

And what is the difference between UNICODE and _UNICODE? (I think you got your cout and wcout around the wrong way there too.)

Share on other sites
The difference between UNICODE and _UNICODE is mostly historical. All well behaved programs that define either should define both.

Share on other sites
To be completely honest, I don't think there's any point in using T-strings these days. T-strings seem primarily designed to allow you to write for Unicode while still allowing you to compile a separate ANSI-string version for the older Windows versions that don't have sufficient Unicode support (95, 98 and ME). However, since the Microsoft Layer for Unicode was released, your Unicode version will work on the older Windows versions as well. I'd rather just assume Unicode support and be done with it. :-)

Share on other sites
Quote:
 Original post by DefendAh, thank you. Should have thought of defining my own one sooner.But now I'm curious about these new things mentioned... #define is evil? Actually I'm getting linker errors using the ostream& way.. using #define does get it to compile.

#define should not be used when there is a way to accomplish the same goal using compiler constructs, and not preprocessor constructs. Consider the case of using #define TWO 2 vs. const int TWO = 2. They accomplish nearly the same goal but the latter is definately better.

I wouldn't go so far as to say #define is always evil...it has its uses.

Share on other sites
evil (but do understand "evil").

As for the reference, I don't know why it wouldn't be working for you. It looks OK to me but I've had problems trying to work with ostream references before... :(

Share on other sites
Quote:
 Original post by Zahlman#ifdef UNICODEostream& tcout = wcout;#elseostream& tcout = cout;#endif

I think you should define tcout as wostream when working in unicode. Like this:
#ifdef UNICODEwostream &tcout = wcout;#elseostream &tcout = cout;#endif

It compiles in VS 2005 and works fine.

Share on other sites
You might as well go an extra step and introduce a typedef for the stream type:
typedef std::basic_ostream<TCHAR> tostream;#ifdef UNICODEtostream & tcout = wcout;#elsetostream & tcout = cout;#endif

Share on other sites
It's like any global variable: if you declare and define the reference in a header, then include that header in multiple compilation units and link them together, the linker is going to complain about multiple definitions. So, as usual, you need to declare it extern in your header, and then define it in one source file:

// foo.h:typedef std::ostream<TCHAR> tostream;extern tostream &tcout;...// foo.cpp:#include "foo.h"...#ifdef UNICODE  tostream &tcout = std::cout;#else  tostream &tcout = std::wcout;#endif

Share on other sites
Let's take that one step further and make that file for *just* handling the streams, and give it a decent name:

// tiostream.h#ifndef TIOSTREAM_H#define TIOSTREAM_H#include <iostream>// We won't put our references into the std namespace because that isn't nice// and we'll leave on a .h extension to indicate that we aren't a standard// library filetypedef std::ostream<TCHAR> tostream;typedef std::istream<TCHAR> tistream;extern tostream &tcout;extern tistream &tcin;#endif// tiostream.h#include "tiostream.h"#ifdef UNICODE  tostream& tcout = std::wcout;  tistream& tcin = std::wcin;#else  tostream& tcout = std::cout;  tistream& tcin = std::cin;#endif

Now you can just include tiostream.h instead of iostream. :) (You *could* put the names into namespace std I guess, or perhaps preferably into your own namespace...)

Share on other sites
Wow, thank you all.

Share on other sites
typedef templates are not permitted in the official C++ standards. you will see compile errors with .NET C++'s compiler

Share on other sites
Quote:
 Original post by Anonymous Postertypedef templates are not permitted in the official C++ standards. you will see compile errors with .NET C++'s compiler

And you see typedef templates in this thread where?

Share on other sites
Nobody has proposed a template typedef. The typedefs used in this thread are all typedefs of template instantiations, which are perfectly legal, i.e.:
template < typename Type >class Thing{	// stuff};// template typedef (possible syntax) - not valid standard C++// template < typename Type >// typedef Thing< Type > OtherNameForThing// OtherNameForThing< int > onft;// template typedef (proposed C++0x syntax) - not yet valid standard C++// template < typename Type >// using OtherNameForThing = Thing< Type >// OtherNameForThing< int > onft;// typedef of template instantiation - perfectly valid standard C++typedef Thing< int > IntThing;IntThing it;

Enigma

(SiCrane well and truely beat me to it because I went looking for the proposed C++0x template typedef syntax).

Share on other sites
Original post by Zahlman
I just have to be pedantic. Consider it a personality flaw.
// tiostream.h#ifndef TIOSTREAM_H#define TIOSTREAM_H#include <istream> // for std::basic_istream#include <ostream> // for std::basic_ostream// We won't put our references into the std namespace because that isn't nice// and we'll leave on a .h extension to indicate that we aren't a standard// library filetypedef std::basic_ostream<TCHAR> tostream;typedef std::basic_istream<TCHAR> tistream;extern tostream &tcout;extern tistream &tcin;#endif// tiostream.cpp#include "tiostream.h"#include <iostream> // for std::[w]cin and std::[w]cout#ifdef UNICODE  tostream& tcout = std::wcout;  tistream& tcin = std::wcin;#else  tostream& tcout = std::cout;  tistream& tcin = std::cin;#endif