上へ戻る  ホームへ戻る

文字コード変換(ShiftJIS←→JIS)



 文字コードの変換を行うありふれたルーチンです。
 「is_kanji1st(c)」というマクロはフィンローダ氏のホームページにある初級C言語Q&Aの(15)凝ったアルゴリズム 【シフトJISの1バイト目の判定】から教わりました。詳しい説明もそこにあります。
 JIS X0208-1990の2バイト文字エスケープシーケンスは「1B 26 40 1B 24 42」ですが、現実にはWindowsのソフトではこれをサポートしていないようです。「1B 24 42」はJIS X0208-1983の2バイト文字エスケープシーケンスです。


#define is_kanji1st(c) ((unsigned int) (c ^ 0x20) - 0xa1 < 0x3c)   // Shift-JIS 1文字目判定
#define SHIFT2B "\x1b\x24\x42"      // JIS 2バイト文字エスケープ
#define SHIFT1B "\x1b\x28\x42"      // JIS 1バイト文字エスケーブ

//---------------------------------------------------------------------------
// JIS -> SJIS 変換
//
//     IN  : asIn = 入力文字列(JIS)
//     OUT : 文字列(ShiftJIS)
//
AnsiString __fastcall TForm1::JIS2SJIS(AnsiString asIn)
{
    int i;
    unsigned char cWk0, cWk1;
    AnsiString asWk, asOut;
    bool bShift = false;
    int iRowOffset, iCellOffset;

    asOut = "";
    for(i = 1; i < asIn.Length() + 1; i++)
    {
        if (asIn[i] == 0x1b)        // ESCコード?
        {
            i++;
            cWk0 = asIn[i++];
            cWk1 = asIn[i];
            if (cWk0 == 0x24)       // 2Byteシフト?
                bShift = true;
            else if (cWk0 == 0x28)  // 1Byteシフト?
                bShift = false;
            continue;
        }

        // 漢字
        if (bShift == true)
        {
            cWk0 = asIn[i++];
            cWk1 = asIn[i];

            // JISコード→Shift JISコード変換
            iRowOffset = cWk0 < 0x5f ? 0x70 : 0xb0;
            iCellOffset = cWk0 % 2 ? (cWk1 > 0x5f ? 0x20 : 0x1f) : 0x7e;
            asOut += (char)(((cWk0 + 1) >> 1) + iRowOffset);
            asOut += (char)(cWk1 + iCellOffset);
        }

        // ASCII
        else
        {
            asOut += asIn[i];
        }
    }
    return asOut;
}

//---------------------------------------------------------------------------
// SJIS -> JIS 変換
//
//     IN  : asIn = 入力文字列(ShiftJIS)
//     OUT : 文字列(JIS)
//
AnsiString __fastcall TForm1::SJIS2JIS(AnsiString asIn)
{
    int i;
    unsigned char cWk0, cWk1;
    char cJISMoji[3];
    AnsiString asWk, asOut;
    bool bShift = false;
    int iRowOffset, iCellOffset, iAdjust;

    cJISMoji[2] = '\0';
    asOut = "";
    for(i = 1; i < asIn.Length() + 1; i++)
    {
        cWk0 = asIn[i];
        if (is_kanji1st(cWk0))          // Shift JISコード1文字目判定
                                        //     0x81 <= cWk0 < 0xa0
                                        //  or 0xe0 <= cWk0 <= 0xfc
        {
        // 漢字
            if (bShift == false)
            {
                asOut += SHIFT2B;       // シフトコード書き込み
                bShift = true;
            }
            i++;
            cWk1 = asIn[i];
            iAdjust = cWk1 < 0x9f;
            iRowOffset = cWk0 < 0xa0 ? 0x70 : 0xb0;
            iCellOffset = iAdjust ? (cWk1 > 0x7f ? 0x20 : 0x1f) : 0x7e;
            cJISMoji[0] = (unsigned char)(((cWk0 - iRowOffset) << 1) - iAdjust);
            cJISMoji[1] = (unsigned char)(cWk1 - iCellOffset);
            asOut += cJISMoji;
        }

        // ASCII
        else
        {
            if (bShift == true)
            {
                asOut += SHIFT1B;       // シフトコード書き込み
                bShift = false;
            }
            asOut += asIn[i];
        }
    }
    if (bShift == true)             // 最後に2Byteシフト状態のままなら
        asOut += SHIFT1B;           // 1Byteシフトコードを書き込む
    return asOut;
}


上へ戻る  ホームへ戻る