Я думаю, что он заменяет недопустимые единицы кода символом замены (U + FFFD), как это предусмотрено стандартом Unicode.Следующий код
#define STRICT
#define UNICODE
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <cstdlib>
#include <iostream>
#include <iomanip>
void test(bool ignore_illegal) {
const DWORD flags = ignore_illegal ? 0 : MB_ERR_INVALID_CHARS;
WCHAR buf[0x100];
SetLastError(0);
const int res = MultiByteToWideChar(CP_UTF8, flags, "test\xFF\xFF test", -1, buf, sizeof buf);
const DWORD err = GetLastError();
std::cout << "ignore_illegal = " << std::boolalpha << ignore_illegal
<< ", result = " << std::dec << res
<< ", last error = " << err
<< ", fifth code unit = " << std::hex << static_cast<unsigned int>(buf[5])
<< std::endl;
}
int main() {
test(false);
test(true);
std::system("pause");
}
выдает следующий вывод в моей системе Windows 7:
ignore_illegal = false, result = 0, last error = 1113, fifth code unit = fffd
ignore_illegal = true, result = 12, last error = 0, fifth code unit = fffd
Таким образом, коды ошибок остаются прежними, но длина уменьшается на два, указывая на двакодовые точки замены, которые были вставлены.Если вы запускаете мой код на XP, пятая кодовая точка должна быть U + 0020 (символ пробела), если две недопустимые единицы кода были удалены.