📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

 
164行目: 164行目:
<br><br>
<br><br>


== BOM (Byte Order Mark) ==
== BOM (Byte Order Mark) 一覧 ==
UTF-8では、ファイルの先頭にUTF-8であることを示す3バイトのBOM (Byte Order Mark) 0xEF、0xBB、0xBFが付加されている場合がある。<br>
BOMは、テキストファイルの先頭に配置され、文字エンコーディングやバイトオーダーを示すためのバイト列である。<br>
BOMが付加されていないUTF-8を、UTF-8NまたはBOM無しUTF-8と呼ぶ。<br>
<br>
<br>
* BOMの使い分け
<center>
** BOM付きUTF-8
{| class="wikitable"
**: Windowsのメモ帳などで推奨。
|+ 各エンコーディングのBOM一覧
**: 文字コードの自動判定に有効。
|-
** BOM無しUTF-8
! エンコーディング !! BOM (16進数) !! バイト数 !! 備考
**: Webアプリケーション、HTML、XML、JSON等で推奨。
|-
| UTF-8 || EF BB BF || 3 || バイトオーダーの概念がないため、エンコーディング識別用のシグネチャとして使用
|-
| UTF-16 BE || FE FF || 2 || ビッグエンディアン (上位バイトが先)
|-
| UTF-16 LE || FF FE || 2 || リトルエンディアン (下位バイトが先)、Windowsで一般的
|-
| UTF-32 BE || 00 00 FE FF || 4 || ビッグエンディアン
|-
| UTF-32 LE || FF FE 00 00 || 4 || リトルエンディアン
|-
| UTF-7 || 2B 2F 76 38<br>2B 2F 76 39<br>2B 2F 76 2B<br>2B 2F 76 2F || 4 || 4バイト目は複数パターンあり (非推奨エンコーディング)
|-
| UTF-1 || F7 64 4C || 3 || ほとんど使用されない
|-
| UTF-EBCDIC || DD 73 66 73 || 4 || EBCDIC環境向け、ほとんど使用されない
|-
| SCSU || 0E FE FF || 3 || Standard Compression Scheme for Unicode
|-
| BOCU-1 || FB EE 28 || 3 || Binary Ordered Compression for Unicode
|-
| GB 18030 || 84 31 95 33 || 4 || 中国国家規格、BOMはオプション
|}
</center>
<br>
<br>
* UTF-8のファイルを出力する際にBOMを付加する例
<u>※注意</u><br>
* <u>UTF-16とUTF-32では、BOMがバイトオーダーの識別に重要である。</u>
* <u>UTF-16でBOMが無い場合、仕様上はビッグエンディアンとして扱うことが推奨されている。</u>
* <u>UTF-32 LEのBOM (FF FE 00 00) は、UTF-16 LEのBOM (FF FE) で始まるため、判定時は4バイト先読みが必要となる。</u>
<br>
下表に、実務上よく使用される4種類の文字コードを示す。<br>
<br>
<center>
{| class="wikitable"
|+ 主要なエンコーディングと用途
|-
! エンコーディング !! 用途
|-
| UTF-8<br>(BOM付き / なし) || Web、クロスプラットフォーム開発で最も一般的
|-
| UTF-16 LE || Windows API (Win32) で内部的に使用
|-
| UTF-16 BE || MacOS、Javaで使用されることがある、
|-
| UTF-32 || 固定長が必要な特殊用途
|}
</center>
<br>
以下の例では、各UNICODEの判定をしている。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  #include <fstream>
  #include <fstream>
  #include <cstring>
  #include <cstdint>
   
   
  // BOMの定義
  enum class TextEncoding
  const unsigned char UTF8_BOM[3] = {0xEF, 0xBB, 0xBF};
  {
    Unknown,
    UTF8_BOM,
    UTF8_NoBOM,
    UTF16_BE,
    UTF16_LE,
    UTF32_BE,
    UTF32_LE
};
   
   
  // ファイルへの書き込み例
  TextEncoding DetectBOM(const std::string& filename)
bool WriteUTF8File(const std::string& filename, const std::string& utf8Text, bool withBOM = true)
  {
  {
     std::ofstream ofs(filename, std::ios::binary);
     std::ifstream ifs(filename, std::ios::binary);
     if(!ofs)
     if (!ifs) {
    {
       return TextEncoding::Unknown;
       return false;
     }
     }
   
   
     // BOMを書き込む (必要な場合)
    unsigned char bom[4] = {0};
     if(withBOM)
    ifs.read(reinterpret_cast<char*>(bom), 4);
    {
    std::streamsize bytesRead = ifs.gcount();
       ofs.write(reinterpret_cast<const char*>(UTF8_BOM), 3);
     // UTF-32 (4バイト) を先に判定
     if (bytesRead >= 4) {
      if (bom[0] == 0x00 && bom[1] == 0x00 && bom[2] == 0xFE && bom[3] == 0xFF) {
          return TextEncoding::UTF32_BE;
      }
       if (bom[0] == 0xFF && bom[1] == 0xFE && bom[2] == 0x00 && bom[3] == 0x00) {
          return TextEncoding::UTF32_LE;
      }
     }
     }
   
   
     // UTF-8テキストを書き込む
     // UTF-8 (3バイト)
     ofs.write(utf8Text.c_str(), utf8Text.size());
     if (bytesRead >= 3) {
      if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) {
    return ofs.good();
          return TextEncoding::UTF8_BOM;
}
      }
</syntaxhighlight>
    }
<br>
C++ 17以降では、<code>std::filesystem</code> を使用してより安全な実装が可能である。<br>
<syntaxhighlight lang="c++">
#include <fstream>
#include <string>
#include <filesystem>
#include <vector>
   
   
namespace fs = std::filesystem;
    // UTF-16 (2バイト)
    if (bytesRead >= 2) {
      if (bom[0] == 0xFE && bom[1] == 0xFF) {
          return TextEncoding::UTF16_BE;
      }
   
   
bool WriteUTF8File(const fs::path& filepath, const std::string& utf8Text, bool withBOM = true)
      if (bom[0] == 0xFF && bom[1] == 0xFE) {
{
          return TextEncoding::UTF16_LE;
    std::ofstream ofs(filepath, std::ios::binary);
       }
    if(!ofs)
    {
       return false;
     }
     }
   
   
     // BOMを書き込む
     return TextEncoding::UTF8_NoBOM;  // BOMなし (またはASCII等)
    if(withBOM)
    {
      constexpr unsigned char UTF8_BOM[] = {0xEF, 0xBB, 0xBF};
      ofs.write(reinterpret_cast<const char*>(UTF8_BOM), sizeof(UTF8_BOM));
    }
   
    // UTF-8テキストを書き込む
    ofs << utf8Text;
    return ofs.good();
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>