Недавно я столкнулся с очень странной проблемой: мое консольное приложение не вообще выдало какой-либо вывод в Windows 7 и Windows Vista, тогда как в Windows 8.1 или no возникла проблема. Windows 10.
После большого количества испытаний я смог отследить это до fputws()
, очевидно, полностью сломанным в Windows 7 и Windows Vista - он просто не производит какой-либо вывод привсе - тогда как fwprintf()
, кажется, работает просто отлично. Хуже того, когда мы звоним fputws()
, кажется, что все портится, и даже fwprintf()
перестает работать. Нет такая проблема в Windows 8.1 или 10.
Примечание: Проблема только появляется, если мы установили stdout / stderrв режим UTF-8 через _setmode()
. Но это требуется , потому что без него любая широкая строка, содержащая не-ANSI символы, будет не напечатана правильно - все символы не-ANSI будут заменены на ?
, что, например,, полностью портит имена файлов. _setmode()
имеет важное значение!
Обратите также внимание, что тема явно , а не о печати на консоль напрямую через Win32 API, например, через WriteConsoleW()
- это совсем другая история. Эта тема о печати на консоль с использованием «стандартных» методов CRT и, более конкретно, об ошибке в Microsoft CRT (MSVCRT.DLL).
(Также обратите внимание, что ясвязывание с предоставляемым системой MSVCRT.DLL
)
Вот минимальный пример программы (включая исходный код и двоичные файлы), который демонстрирует ошибку:
http://www.mediafire.com/file/2cn5yz8m43x215d/fputws_test.zip/file
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#define PRINT(TXT, OUT) fputws(TXT, OUT)
//#define PRINT(TXT, OUT) fwprintf(OUT, L"%s", TXT)
int wmain(int argc, wchar_t* argv[])
{
_setmode(_fileno(stderr), _O_U8TEXT);
PRINT(L"Hello world! \x04a\x0f6\x072\x067 "
L"\x062\x0e4\x063\x06b\x074 \x048\x061\x078\x065\x06e\x066\x0fc\x0df\x065, "
L"\x412\x43b\x430\x434\x438\x43c\x438\x440, "
L"\x056\x075\x10d\x069\x107, "
L"\x392\x3b1\x3c1\x3bf\x3c5\x3c6\x3ac\x3ba\x3b7\x3c2\n", stderr);
PRINT(L"Goodbye cruel world...\n", stderr);
return getchar();
}
Результат в Windows Vista (не работает):
https://i.imgur.com/7GJKfu5.png
Результат в Windows 7 (не работает):
https://i.imgur.com/QPg6frX.png
Результат в Windows 8.1 (хорошо):
https://i.imgur.com/NErLivY.png
Результат в Windows 10 v1903 (хорошо):
https://i.imgur.com/MWpKLl4.png
На приведенном выше снимке экрана показано, что _setmode(..., _O_U8TEXT)
в сочетании с fputws()
или fwprintf()
прекрасно работает для печати строк Unicode на консоли Windows в всех версиях Windows. Это также показывает, что fputws()
, но не fwprintf()
, сломано в Windows 7 ранее.
Как могло случиться, что такая серьезная ошибка в фундаментальной функции CRT осталась незамеченной ???
(... или я что-то здесь упускаю?)
Спасибои наилучшими пожеланиями
MuldeR