• Advertisement
Sign in to follow this  

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites

#ifdef UNICODE
ostream& tcout = wcout;
#else
ostream& 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 this post


Link to post
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 this post


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

Share this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Defend
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.


#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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Zahlman

#ifdef UNICODE
ostream& tcout = wcout;
#else
ostream& tcout = cout;
#endif



I think you should define tcout as wostream when working in unicode. Like this:

#ifdef UNICODE
wostream &tcout = wcout;
#else
ostream &tcout = cout;
#endif

It compiles in VS 2005 and works fine.

Share this post


Link to post
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 UNICODE
tostream & tcout = wcout;
#else
tostream & tcout = cout;
#endif

Share this post


Link to post
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 this post


Link to post
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 file

typedef 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 this post


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

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
typedef 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 this post


Link to post
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 this post


Link to post
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 file

typedef 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



Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement