2017-01-23 9 views
2

単純なテキストファイルにUTF-8 BOMを手動で追加する必要があります。しかし、以下の方法でBOMを書くことはできません。私のかなり限定されたC++の知識では、私は実際に私が間違っていることを理解していません。私はそれが3バイトしか書かないという事実に関連していなければならないと思っています。システムは何らかの理由で2の倍数を書き込むことを期待しています。コードはUnicode Character Setでコンパイルされます。 私に正しい方向を指し示すヒントがあれば歓迎します。UTF-8 BOMの作成時の例外の取得

FILE* fStream; 
errno_t e = _tfopen_s(&fStream, strExportFile, TEXT("wt,ccs=UTF-8")); //UTF-8 

if (e != 0) 
{ 
    //Error Handling 
    return 0; 
} 

CStdioFile* fileo = new CStdioFile(fStream); 
fileo->SeekToBegin(); 

//Write BOM 
unsigned char bom[] = { 0xEF,0xBB,0xBF }; 
fileo->Write(bom,3); 
fileo->Flush(); //BOOM: Assertion failed buffer_size % 2 == 0 
+0

私はあなたの質問をよく理解していません。 [_tfopen_s documentation](https://msdn.microsoft.com/en-us/library/z5hh6ee9.aspx)から:* "Unicodeモードで書き込むために開かれたファイルには、BOMが自動的に書き込まれます。書き込みのためにファイルを開いており、Unicodeモードを有効にしているため、BOMを手作業で書き出す必要はありません。 – IInspectable

+0

@IInspectable私はそれがドキュメントの中に残っていることに同意します - しかし、私はBOMが上記のコード行を使用するときに自動的に書かれたことを経験したことはありません。 – Marwie

答えて

2

Microsoft's documentation for _tfopen_sによれば、(強調追加):ユニコードストリームI/O機能はテキストモード(デフォルト)で動作するとき

、送信元または送信先ストリームは、シーケンスであると仮定されますのマルチバイト文字。したがって、Unicodeストリーム入力関数は、マルチバイト文字をワイド文字に変換します(mbtowc関数を呼び出す場合と同様)。同じ理由から、Unicodeストリーム出力関数は、ワイド文字をマルチバイト文字に変換します(wctomb関数を呼び出した場合と同じように)。

あなたは、その後に変換されたファイルにUTF-16文字を書くことが期待されています。 3バイトのシーケンス0xEF,0xBB,0xBFの代わりに、単一の16ビット0xfeffを書き込む必要があります。

+0

あなたは絶対に 'unsigned char bom [] = {0xff、0xfe};と置き換えて、2バイトを書くことで問題は解決しました。配列に格納するときは、0xfeと0xffの順番を交換しなければならなかったことに注意してください。なぜどんなアイデア? – Marwie

+1

@Marwieあなたは[x86プロセッサがリトルエンディアンであるため]バイトをスワップする必要があります(http://stackoverflow.com/questions/5185551/why-is- x86リトルエンディアン)。代わりに 'uint16_t'や' wchar_t'を書いたのであれば、それを心配する必要はありません。バイトは既にメモリに入れ替えられています。 –

関連する問題