"sanitize_for_utf8": Convert EUC-JP or SJIS strings to UTF-8 utilities in C
hacker emblem Happy Hacking!


English Here (machine translation)

sanitize_for_utf8: EUC-JP あるいは SJIS エンコード文字列を UTF-8 で文字化けしないように変換するためのユーティリティ

この C 言語ユーティリティは、EUC-JP (拡張 Unix 日本語文字コード) あるいは SJIS (シフト JIS 文字コード) でエンコードされている文字列を、文字化けしないように UTF-8 文字コードに変換するためのものです。
このユーティリティには次の API を含みます。

  • sanitize_for_utf8() : EUC-JP あるいは SJIS でエンコードされているバッファの内容を編集して、UTF-8 に変換した場合に文字化けしてしまう文字列部分を指定した ASCII コードで置き換える
  • to_utf8() : EUC-JP あるいは SJIS でエンコードされているバッファを、文字化けしないように UTF-8 に変換する
  • from_utf8() : UTF-8 でエンコードされているバッファを、EUC-JP あるいは SJIS に変換する

API を使用するためのヘッダは utf8.h で、API の実装は utf8.c です。API の説明は、この文書で後述しています。

テスト・プログラム utf8_test.c そして make ファイル Makefile を記述しました。


API の説明

  1. EUC-JP/SJIS エンコードされたバッファ内で、UTF-8 に変換すると文字化けしてしまう文字列部分を ASCII コードで置き換える sanitize_fro_utf8()
    unsigned char *sanitize_for_utf8(Sanitize_for_UTF8_e    str_encoding
    , size_t length
    , unsigned char *str
    , char replace_code
    , unsigned long how
    );

    str_encoding に、EUC-JP エンコードされたバッファを処理する場合は Sanitize_for_UTF8_e_EUCJP、Sanitize_for_UTF8_e_EUC_JISX0213、Sanitize_for_UTF8_e_EUCJP_OPEN、Sanitize_for_UTF8_e_EUCJP_WIN、Sanitize_for_UTF8_e_EUCJP_MS のいずれかを、SJIS エンコードされたバッファを処理する場合は Sanitize_for_UTF8_e_SJIS、Sanitize_for_UTF8_e_SJIS_OPEN、Sanitize_for_UTF8_e_SJIS_WIN のいずれかを指定します。
    length にはバッファ内で処理対象とする文字列長をバイト単位で指定します。
    str には処理を行うバッファのアドレスを指定します。
    replace_code には、UTF-8 に変換した場合に文字化けしてしまう部分文字列の各バイトを置き換える ASCII 文字コードを指定します。nil ('\0') は指定できません。
    how には、Sanitize_for_UTF8_Default_how、Sanitize_for_UTF8_Pass_hankaku_kana、Sanitize_for_UTF8_Pass_extra_characters のいずれかあるいはこれらの論理和を指定して、replace_code で置き換える文字種を指定します。

    この API では、UTF-8 に変換した場合に文字化け (garbled) してしまう可能性がある文字種を以下のものとしています。

    1. JIS X 0201 の半角カタカナ

      EUC-JP では 0x8e で始まる 2 バイト文字のすべて ("\x8e\x21" 〜 "\x8e\x5f")、SJIS では 0xa1 から 0xdf 範囲の 1 バイト文字のすべて

    2. いわゆる機種依存文字 (丸付き数字、ローマ数字、単位表記、年号、カッコつき株記号など)、および、EUC-JP の外字区画 (最初のバイトが '\x8f' である 3 バイト漢字文字) にあたる JIS X 0212 補助漢字 (JIS X 0213 の場合は JIS X 0208 外の漢字文字)。

      JIS 第一水準漢字 (JIS 区点) 02-15〜02-25、02-34〜02-41、02-49〜02-59、02-75〜02-81、02-90〜02-93、03-01〜03-15、03-26〜03-32、03-59〜03-64、03-91〜03-94、04-84〜04-94、05-87〜05-94、06-25〜06-32、06-57〜06-94、07-34〜07-47、07-82〜07-94、08-33〜08-94、09-01〜09-94、10-01〜10-94、11-01〜11-94、12-01〜12-94、13-01〜13-94 (丸付き数字、ローマ数字、単位表記、年号など)、14-01〜14-94、15-01〜15-94、47-52〜47-94

      JIS 第二水準漢字 (JIS 区点) 84-97〜84-94、85-01〜85-94、86-01〜86-94、87-01〜87-94、88-01〜88-94、89-01〜89-94 (\〜コ)、90-01〜90-94 (サ〜[)、91-01〜91-94 (\〜コ)、92-01〜92-94 (サ〜W)、93-01〜93-94、94-01〜94-94

    正常に処理できた場合は、str の値を返します。なんらかのエラーが発生した場合は NULL を返し、エラーの詳細を errno に出力します。errno の値と意味は以下のとおりです。

    • EINVAL : 不正な引数が渡された場合

  2. EUC-JP あるいは SJIS でエンコードされているバッファを、文字化けしないように UTF-8 に変換する to_utf8()
    unsigned char *to_utf8(Sanitize_for_UTF8_e    inbuf_encode
    , unsigned char *inbuf
    , size_t inbuf_length
    , char replace_code
    , unsigned char *outbuf
    , size_t outbuf_size
    , char padding_code
    , unsigned long how
    );

    inbuf_encoding に、EUC-JP エンコードされたバッファを処理する場合は Sanitize_for_UTF8_e_EUCJP、Sanitize_for_UTF8_e_EUC_JISX0213、Sanitize_for_UTF8_e_EUCJP_OPEN、Sanitize_for_UTF8_e_EUCJP_WIN、Sanitize_for_UTF8_e_EUCJP_MS のいずれかを、SJIS エンコードされたバッファを処理する場合は Sanitize_for_UTF8_e_SJIS、Sanitize_for_UTF8_e_SJIS_OPEN、Sanitize_for_UTF8_e_SJIS_WIN のいずれかを指定します。
    inbuf には EUC-JP あるいは SJIS でエンコーディングされているバッファのアドレスを指定します。
    inbuf_length には変換処理の対象文字列長をバイト単位で指定します。
    replace_code には UTF-8 に変換すると文字化けしてしまう部分文字列の各バイトを置き換える ASCII コード を指定します。nil '\0' を指定した場合、字化けする部分文字列の各バイトは半角空白 0x20 で置き換えられます。置き換えられる文字については、sanitize_for_utf8() の API 説明を参照してください。
    outbuf には、inbuf を UTF-8 に変換した結果を出力します。
    outbuf_size には、outbuf に出力できる最大のバイト数を指定します。
    padding_code には、変換後の UTF-8 文字列の末尾に付加するパディング文字を ASCII コードで指定します。nil '\0' を指定すると、変換結果を文字列として終端することになります。
    how には、半角円記号 ¥ (\x5c) とチルダ ~ (\x7e) の変換処理および replace_code で置き換える文字種についての指示を、以下のマクロの論理和で指定します。

    • Sanitize_for_UTF8_Default_how (== 0UL):

      半角カタカナと機種依存文字を含む JIS 補助漢字は、replace_code で置き換えられます。EUC-JP エンコードされている場合は 2 バイト分あるいは 3 バイト分の変換元のバイトが replace_code で置き換えられます。SJIS エンコードされている場合は 1 バイト分あるいは 2 バイト分の変換元のバイトが置き換えられます。
      半角円記号 ¥ (0x5c) は UTF-8 の円記号 (U+00A5: "\xc2\xa5") に、チルダ ~ (0x7e) は UTF-8 でもそのまま変わらずに変換されます。UTF-8 側での文字の表示は EUC-JP あるいは SJIS 上での表示と変わりません。が、半角円記号については UTF-8 変換後のサイズが 2 バイト長の文字列となります。

    • Sanitize_for_UTF8_Yen_sign_must_be_U005C (== 1UL):

      半角円記号 ¥ (0x5c) は UTF-8 側でも文字コードは変わらず 0x5c のままになります。UTF-8 側での表示はバックスラッシュ (逆向きのスラッシュ) になります。UTF-8 変換後のサイズは変換元と変わりません。

    • Sanitize_for_UTF8_Tilde_must_be_U203E (== 2UL):

      チルダ ~ (\x7e) は UTF-8 のチルダ記号 (U+203E: "\xe2\x80\xbe") に変換されます。UTF-8 側では全角記号として表示されます。が、UTF-8 変換後のサイズは 3 バイト長の文字列になります。

    • Sanitize_for_UTF8_Pass_hankaku_kana (== 4UL):

      半角カタカナ文字を replace_code で置き換えずに、UTF-8 の該当する文字へ変換します。

    • Sanitize_for_UTF8_Pass_extra_characters (== 8UL):

      JIS 補助漢字を replace_code で置き換えずに、UTF-8 の該当する文字へ変換します。

    正常に UTF-8 へエンコード変換できた場合は変換結果バッファのアドレス (outbuf の値) を返します。
    なんらかのエラーが発生した場合は、NULL を返し、以下の意味を示す errno を出力します。

    • EINVAL: 不正な引数を指定した場合
    • ENOMEM: 文字の置き換え用あるいはエンコード処理用の動的メモリを獲得できない場合 (メモリ不足)
    • EPERM: iconv(3) POSIX ライブラリ関数が、EUC-JP、SJIS あるいは UTF-8 のいずれかのエンコードを提供していない場合
    • EILSEQ: inbuf 内の文字列に不正な文字コード・シーケンスが存在する場合

  3. UTF-8 でエンコードされているバッファを、EUC-JP あるいは SJIS に変換する from_utf8()
    unsigned char *from_utf8(Sanitize_for_UTF8_e    outbuf_encode
    , unsigned char *inbuf
    , size_t inbuf_length
    , unsigned char *outbuf
    , size_t outbuf_size
    , char padding_code
    );

    outbuf_encode に、EUC-JP エンコードされたバッファを処理する場合は Sanitize_for_UTF8_e_EUCJP、Sanitize_for_UTF8_e_EUC_JISX0213、Sanitize_for_UTF8_e_EUCJP_OPEN、Sanitize_for_UTF8_e_EUCJP_WIN、Sanitize_for_UTF8_e_EUCJP_MS のいずれかを、SJIS エンコードされたバッファを処理する場合は Sanitize_for_UTF8_e_SJIS、Sanitize_for_UTF8_e_SJIS_OPEN、Sanitize_for_UTF8_e_SJIS_WIN のいずれかを指定します。
    inbuf には、UTF-8 エンコードされているバッファのアドレスを指定します。
    inbuf_length にはエンコード変換する対象バッファのサイズをバイト単位で指定します。
    outbuf にはエンコード変換した結果を出力します。
    outbuf_size には、outbuf に出力できる最大サイズをバイト単位で指定します。
    padding_code には変換後の文字列の末尾に付加するパディング文字を ASCII コードで指定します。nil '\0' を指定すると、変換結果を文字列として終端することになります。

    変換元の UTF-8 文字列に冗長なコード表現 (1 バイトで表せる文字列を 2 バイト以上の UTF-8 文字列として表現してある場合) されているものは、すべて対応する正規の UTF-8 エンコード文字に縮退させてからエンコード変換されます。

    正常に EUC-JP あるいは SJIS へエンコード変換できた場合は変換結果バッファのアドレス (outbuf の値) を返します。
    なんらかのエラーが発生した場合は、NULL を返し、以下の意味を示す errno を出力します。

    • EINVAL: 不正な引数を指定した場合
    • ENOMEM: エンコード処理用の動的メモリを獲得できない場合 (メモリ不足)
    • EPERM: iconv(3) POSIX ライブラリ関数が、EUC-JP、SJIS あるいは UTF-8 のいずれかのエンコードを提供していない場合
    • EILSEQ: inbuf 内の文字列に不正な文字コード・シーケンスが存在する場合