pit-rayの備忘録

開発中に得た知識を記事にしていくブログ

【C++】ofstreamでUTF-8 with BOMを出力する方法

今回は、C++の標準ライブラリのfstreamのwrite関数を用いた、バイトオーダーマーク(BOM)の付け方をご紹介します。

codecvtを用いた方法もあるようですが、私の環境ではうまくできなかったため、直接バイナリデータを書きこむ方法を用います。

バイトオーダーマークの説明をWikipediaから引用すると、以下のようにあります。

Unicodeの符号化形式で符号化したテキストの先頭につける数バイトのデータのことである
~中略~
プログラムがテキストデータを読み込む時、その先頭の数バイトからそのデータがUnicodeで表現されていること、また符号化形式(エンコーディング)としてどれを使用しているかを判別できるようにしたものである
(Wikipedia:バイトオーダーマーク - Wikipedia])

つまり、バイトオーダーマークとは、
どのような文字コードを用いて表現されているかを示す、判別用のデータのことです。
わざと冗長性を持たせているわけです。

よって、UTF-8からUTF-8 with BOMへの変換はそこまで難しくはありません。
プログラマーは、出力するファイルがUTF-8と分かっているので、決められたデータを付与するだけです。

テキストの先頭に付けるデータは
UTF-8の場合、
0xEF
0xBB
0xBF

です。

それぞれ、16進数2桁で表されているので、unsigned char型を使うのがベストです。

バイナリに書き込むには以下のようにwrite関数を用います。

#include <iostream>
#include <fstream>

using namespace std ;
int main()
{
    //BOMあり
    ofstream ofs_bom( "u8b" ) ;
    unsigned char bom[] = { 0xEF, 0xBB, 0xBF } ;
    ofs_bom.write( reinterpret_cast<char*>( bom ), sizeof( bom ) ) ;
    ofs_bom << "UTF-8 with BOM" << endl ;

    //BOMなし
    ofstream ofs( "u8" ) ;
    ofs << "UTF-8" << endl ;

    return 0 ;
}

結果

f:id:pit-ray:20181211021923j:plain
バイナリエディタ(Stirling)による確認:BOMなし
f:id:pit-ray:20181211021852j:plain
バイナリエディタ(Stirling)による確認:BOMあり
このようにBOMありには、書き込んだ先頭データがあるのが分かります。

当然、VSCodeなどのエディタで開くと以下のようになります。

f:id:pit-ray:20181211021529j:plain
VSCodeによる判定:BOMなし
f:id:pit-ray:20181211021532j:plain
VSCodeによる判定:BOMあり


以上です。
記事に対してのご意見等は、コメントやお問い合わせフォームからご指摘いただけると幸いです。