WindowsのUTF-8
質問
C WindowsプログラムでコードページをUTF-8に設定するにはどうすればよいですか?
私はfopenを使用してファイルを開くサードパーティのライブラリを持っています。 wcstombsを使用して、Unicodeファイル名を現在のコードページに変換できますが、ユーザーがコードページ外の文字を含むファイル名を持っている場合、これは壊れます。
理想的には、コードページをUTF-8に設定するために_setmbcp(65001)を呼び出すだけですが、_setmbcpのMSDNドキュメントにはUTF-8はサポートされていないと記載されています。
これを回避するにはどうすればよいですか
解決
残念ながら、UnicodeをWindowsの現在のコードページにする方法はありません。 CP_UTF7
および CP_UTF8
定数は擬似コードページであり、 MultiByteToWideChar および WideCharToMultiByte 変換関数(Benが述べたように。
あなたの問題はfstream C ++クラスの問題に似ています。 fstreamコンストラクターは char *
名のみを受け入れ、真のUnicode名を持つファイルを開くことができません。 VCが提供する唯一のソリューションはハックでした。ファイルを個別に開き、ストリームオブジェクトにハンドルを設定します。もちろん、サードパーティのライブラリはおそらくハンドルを受け付けないため、これはあなたにとって選択肢ではないのではないかと思います。
私が考えることができる唯一の解決策は、オリジナルにハードリンクされている非ユニコード名の一時ファイルを作成し、それをパラメータとして使用することです。
他のヒント
すべてのWindows APIは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;
}
そして同様の形式の何かを元に戻します。
2018更新:Windows 10は「65001」を作成しました。コードページレス"擬似" 2つのステップで:
-
conhost
の変更:Linux用Windowsサブシステムは、コンソールにコードページ65001を使用します。 WSL以降、cmd.exe
でchcp 65001
を実行することもできます。 (かなり愚かなPythonのバグが発生しました。) - フル機能のロケール:ビルド17035以降のWindows UTF-8をロケールコードページとして設定できます。これは、2018年4月のアップデートから入手できます。
cygwin(デフォルトでUTF-8ロケールを提供)を使用するか、必要なUTF-8からUTF-16への変換を行い、非標準の _wfopen
などをラップするWindows用の独自のlibcハックを作成します。 。関数。