Подтвердить что ты не робот

UTF-8 в Windows

Как установить кодовую страницу в UTF-8 в программе на C Windows?

У меня есть сторонняя библиотека, которая использует fopen для открытия файлов. Я могу использовать wcstombs для преобразования имен файлов Unicode на текущую страницу кода, однако, если у пользователя есть имя файла с символом вне кодовой страницы, тогда это прерывается.

В идеале я просто позвоню _setmbcp (65001), чтобы установить кодовую страницу в UTF-8, однако в документации MSDN для _setmbcp указано, что UTF-8 не поддерживается.

Как я могу обойти это?

4b9b3361

Ответ 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 и т.д. функции.