Не работает ли сервер fputws () в Windows 7 и Vista? - нет проблем с fwprintf () - PullRequest
0 голосов
/ 03 ноября 2019

Недавно я столкнулся с очень странной проблемой: мое консольное приложение не вообще выдало какой-либо вывод в 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

...