UTF-8 в Windows
Как установить кодовую страницу в UTF-8 в программе на C Windows?
У меня есть сторонняя библиотека, которая использует fopen для открытия файлов. Я могу использовать wcstombs для преобразования имен файлов Unicode на текущую страницу кода, однако, если у пользователя есть имя файла с символом вне кодовой страницы, тогда это прерывается.
В идеале я просто позвоню _setmbcp (65001), чтобы установить кодовую страницу в UTF-8, однако в документации MSDN для _setmbcp указано, что UTF-8 не поддерживается.
Как я могу обойти это?
Ответы
Ответ 1
К сожалению, нет способа сделать Unicode текущую кодовую страницу в Windows. Константы CP_UTF7
и CP_UTF8
являются псевдокодами, которые используются только в MultiByteToWideChar и WideCharToMultiByte, как упоминал Бен.
Ваша проблема аналогична вашей работе с классами класса С++. Конструкторы fstream принимают только имена char*
, что делает невозможным открытие файла с истинным именем Unicode. Единственным решением, предлагаемым VC, был взлом: откройте файл отдельно, а затем установите дескриптор объекта потока. Я боюсь, что это не вариант для вас, конечно, так как сторонняя библиотека, вероятно, не принимает дескрипторы.
Единственное решение, о котором я могу думать, это создать временный файл с именем, отличным от Unicode, который жестко связан с оригиналом и использовать его как параметр.
Ответ 2
Все API Windows думают в UTF-16, поэтому вам лучше писать обертку вокруг вашей библиотеки, которая преобразуется на границах.
Как ни странно, Windows думает, что UTF-8 является кодовой страницей для целей конвертации, поэтому вы используете те же API-интерфейсы, что и для преобразования между кодовыми страницами:
std::wstring Utf8ToUtf16(const char* u8string)
{
int wcharcount = strlen(u8string);
wchar_t *tempWstr = new wchar_t[wcharcount];
MultiByteToWideChar(CP_UTF8, 0, u8string, -1, tempWstr, wcharcount);
wstring w(tempWstr);
delete [] tempWstr;
return w;
}
И что-то похожее для преобразования назад.
Ответ 3
Попробуйте установить кодовую страницу С#pragma
Также вы можете добавить некоторые детали? Если я правильно понял, у вас есть библиотека сторонних разработчиков, которую вы хотите изменить с помощью функции, которая принимает строку const char, и вы хотите передать ей строку Unicode?
Ответ 4
Использовать cygwin (который по умолчанию задает локаль UTF-8) или написать собственный libc-хак для Windows, который выполняет необходимые переводы UTF-8 в UTF-16 и обертывает нестандартные _wfopen
и т.д. функции.