Skip to content

Instantly share code, notes, and snippets.

@DBJDBJ
Last active April 16, 2017 11:31
Show Gist options
  • Save DBJDBJ/9d02f8dbfb0dceef372607af93eb53f2 to your computer and use it in GitHub Desktop.
Save DBJDBJ/9d02f8dbfb0dceef372607af93eb53f2 to your computer and use it in GitHub Desktop.
C++ WINDOWS UNICODE CONSOLE OUTPUT
#pragma once
/*
----------------------------------------------------------------------
ACTUALLY:
http://archives.miloush.net/michkap/archive/2008/03/18/8306597.html
It seems this is very wizard like method?
Try this simeple test and see if it crashes your console:
<pre>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
int main(void) {
_setmode(_fileno(stdout), _O_U16TEXT);
wprintf(L"\x043a\x043e\x0448\x043a\x0430 \x65e5\x672c\x56fd\n");
// following line is very likely to crash the UCRT
printf(L"\x043a\x043e\x0448\x043a\x0430 \x65e5\x672c\x56fd\n");
return 0;
}
</pre>
WARNING FROM BEFORE:
The following is a "hack" and shouild not be applied to the global app env.
It should be used inside functions in a local manner.
Neither "C" API or C++ stdlib, can work normaly if this is executed.
Probably no ANSI output will work at all.
----------------------------------------------------------------------
*/
/*
Copyright 2017 [email protected]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http ://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/* set to 1 if using UTF16 console output */
#define DBJU16 1
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include <Windows.h>
#if DBJU16
#include <io.h>
#include <fcntl.h>
#endif
namespace dbj {
namespace win {
namespace console {
#if DBJU16
/*
WIN console is not unicode U16 by default
thus console output of unicode string will not produce what is expected
For example:
const static std::wstring doubles = L"║═╚";
const static std::wstring singles = L"│─└";
std::wcout << doubles ;
will not work is the following low level intialisatoon of console has not been
performed
*/
namespace {
struct __declspec(novtable)
UINT16CONSOLEINIT
{
unsigned int & counter()
{
static unsigned int counter_ = 0;
return counter_;
}
/*
If you call ::CoInitialize(NULL), after this method is used
most likely the HRESULT will be :
hRes = 0×80010106 — Cannot change thread mode after it is set.
*/
UINT16CONSOLEINIT()
{
const UINT & ctr = (counter())++;
if (0 == ctr) {
/*
To print unicode into the Windows console one has to set it to UNICODE first.
And then set it back so that CRT does not throw. Solution is described here
https://msdn.microsoft.com/en-us/library/tw4k6df8.aspx
*/
if (EOF == fflush(stdout)) {
/* TODO: If fflush returns EOF, data may have been lost due to a write failure. */
}
_setmode(_fileno(stdout), _O_U16TEXT);
/*TODO: log the result here*/
}
}
~UINT16CONSOLEINIT()
{
const UINT ctr = --(counter());
if (ctr < 1) {
/*
apparently must do this
also make sure NOT to mix cout and wcout in the same executable!
*/
if (EOF == fflush(stdout)) {
/* TODO: If fflush returns EOF, data may have been lost due to a write failure. */
}
_setmode(_fileno(stdout), _O_TEXT);
/*TODO: log the result here*/
}
}
};
/*
WARNING! Better do not do this.
Probably no ANSI console output will work after this.
*/
static const UINT16CONSOLEINIT uint16consoleinit__{};
}
#endif // DBJU16
} // console
} // win
} // dbj
/*
If problems with them, one can undef the macros defined in here
#undef WIN32_LEAN_AND_MEAN
#undef VC_EXTRALEAN
*/
@DBJDBJ
Copy link
Author

DBJDBJ commented Apr 16, 2017

ACTUALLY:
http://archives.miloush.net/michkap/archive/2008/03/18/8306597.html
It seems this is very wizard like method?
Try this simeple test and see if it crashes your console:

#include 
#include 
#include 

int main(void) {
    _setmode(_fileno(stdout), _O_U16TEXT);
    wprintf(L"\x043a\x043e\x0448\x043a\x0430 \x65e5\x672c\x56fd\n");
    // following line is very likely to crash the UCRT
    printf(L"\x043a\x043e\x0448\x043a\x0430 \x65e5\x672c\x56fd\n");
    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment