ワイド ストリームは、ワイド ストリーム バッファを使用してファイルにアクセスします。ワイド ストリーム バッファはファイルからバイトを読み取り、その codecvt ファセットを使用してこれらのバイトをワイド文字に変換します。デフォルトの codecvt ファセットはstd::codecvt<wchar_t, char ,std::mbstate_t>
と のネイティブ文字セット間で変換しwchar_t
ますchar
(つまり、mbstowcs(
) が行います)。
ネイティブの char 文字セットを使用していないため、必要なのはUCS-2
、マルチバイト シーケンスとして読み取ってワイド文字に変換する codecvt ファセットです。
#include <fstream>
#include <string>
#include <codecvt>
#include <iostream>
int main(int argc, char *argv[])
{
wifstream fin("en.rc", std::ios::binary); // You need to open the file in binary mode
// Imbue the file stream with a codecvt facet that uses UTF-16 as the external multibyte encoding
fin.imbue(std::locale(fin.getloc(),
new std::codecvt_utf16<wchar_t, 0xffff, consume_header>));
// ^ We set 0xFFFF as the maxcode because that's the largest that will fit in a single wchar_t
// We use consume_header to detect and use the UTF-16 'BOM'
// The following is not really the correct way to write Unicode output, but it's easy
std::wstring sLine;
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> convert;
while (getline(fin, sLine))
{
std::cout << convert.to_bytes(sLine) << '\n';
}
}
ここに問題があることに注意してUTF-16
ください。の目的wchar_t
は、1wchar_t
つのコードポイントを表すことです。ただし、Windows ではUTF-16
、一部のコードポイントを2 つ wchar_t
の として表す which を使用します。これは、標準 API が Windows でうまく機能しないことを意味します。
ここでの結果は、ファイルにサロゲート ペアが含まれている場合、 はcodecvt_utf16
そのペアを読み取り、それを 16 ビットより大きい単一のコードポイント値に変換し、値を 16 ビットに切り捨ててwchar_t
. これは、このコードが実際に制限されていることを意味しますUCS-2
。これを反映するために maxcode テンプレート パラメーターを に設定しました0xFFFF
。
には他にも多くの問題がありwchar_t
、完全に回避したい場合があります: C++ wchar_t の「問題」は何ですか?