cout w/ Win32 console

Started by
4 comments, last by doctorsixstring 21 years, 4 months ago
In this Win32 app, how would I get the standard C++ input/output stream operators (cin & cout) to work with an allocated console? I already know about WriteConsole(), but it would be nice to just use cout. Is this possible?
  
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	AllocConsole();

	cout << "hello";	//doesn''t work


	FreeConsole();

	MessageBox(0,"Program Complete", "", 0);

	return 0;
}
  
Thanks in advance, -Mike
Advertisement
iostreams don''t seem to provide a way to open a file by anything other than its filename (stdio routines can open os file handles and low-level io file handles), so you can implement your own streambuf class that calls WriteConsole, or you can use something like the following hack:

http://www.gamedev.net/community/forums/topic.asp?topic_id=125913

to reassign stdout to console, and cout will end up printing to console too.
I like the idea of reassigning stdout to the console, but I''m unsure of the exact procedure. You mentioned the rdbuf() method in one of the other threads, niyaw. Is that what I want to use?
quote:Original post by doctorsixstring
I like the idea of reassigning stdout to the console, but I''m unsure of the exact procedure.

this is the code i use:
*stdout = *_tfdopen(_open_osfhandle((intptr_t) GetStdHandle(STD_OUTPUT_HANDLE), _O_WRONLY), _T("a")); 

you also want to save *stdout so that you can restore it before program terminates to avoid double-closing files or any other possible weird problems.

the main drawback of this method is that it''s highly non-portable. i assume the following things about stdio implementation:
- by including <stdio.h>, i get the definition of FILE struct, not just a declaration. note that this definition isn''t required for using any stdio functions, and you should treat FILE * as an opaque pointer.
- i can copy FILE structs around without any problems (a reasonable assumption considering that FILE is a C struct and doesn''t have ctors/dtors).
- ''stdout'' is a variable, not a macro resolving to a function, such as

#define stdout (crtInternalGetStdout())

this method works on my vc7, but it may not work on dev-c++, vc6 or vc8. the thing most likely to break is FILE definition in stdio.h, because as i said you never use contents of FILE struct in your code.

there''s freopen() function that, unfortunately, only works with files. what we''re looking for is something like _fdreopen that will reopen a file stream given a low-level io handle, but no such thing exists on msvc.
quote: You mentioned the rdbuf() method in one of the other threads, niyaw. Is that what I want to use?

that''s a non-hackish way, but it comes with problems. here''s how you can reassign cout to a file:

  // open a file streamofstream out("filename");// save cout''s stream bufferstreambuf *sb = cout.rdbuf();// point cout''s stream buffer to that of the open filecout.rdbuf(out.rdbuf());// now you can print to file by writing to coutcout << "Hello, world!";// restore cout''s buffer backcout.rdbuf(sb);  

problem with doing the same thing for console is that a console isn''t a file, and basic_filebuf''s constructor only takes a filename. thus, you need to implement your own streambuf class that will call WriteConsole, create an instance of it, and then use rdbuf() to use it with cout. advantage of this method is that it''s portable across win32 compilers. the obvious disadvantage is that you need to write a custom streambuf class for this to work.

so, it''s either a streambuf implementation, a crt extension (you can write _fdreopen given stdio source), or nonportable hacks. take your pick.
There was an article in CUJ about this very thing.

Basically you make a new type of streambuf object which dumps things to an allocated console.

Then you do the assignment of the streambuf trick.

Or just use an accessor to your special ''ostream'' instance.

Check out www.cuj.com for the details...

I can''t remember it off the top of my head
Adding Console I/O to a Win32 GUI App

This topic is closed to new replies.

Advertisement