CString

[戻る]
かお 2005/03/18(金) 10:38:02
Windows XP 
VC++ 6.0

CStringを使ってSJISからJISへと表示する
ことはできるのでしょうか?

Blue 2005/03/18(金) 10:41:34
CString自体にはそのような機能はありません。
地道に_mbcjmstojisなどをつかって変換するのでしょう。

かお 2005/03/22(火) 10:34:18
ヘルプなどを見ましたが、_mbcjmstojisの使い方が分かりません。
教えて頂けないでしょうか?

uid 2005/03/22(火) 12:23:45
どうわからないのか書かないと、ヘルプをよく読んでくださいとしか答えられません。

Blue 2005/03/22(火) 13:00:26
説明するのメンドイ。実装してみたんでそれ参考にして。
(エスケープ・シーケンスがあっているか怪しいw)

CString SJIStoJIS( const CString& _strText )
{
    const int nLength = _strText.GetLength();   // 入力文字列長

    int     nStrPos;    // 文字位置
    BYTE    byHiByte;   // 上位バイト
    BYTE    byLowByte;  // 下位バイト
    WORD    wCode;      // JISコード用
    CString strResult;  // 変換後文字列
    LPTSTR  lpszResult; // 変換後文字列ポインタ
    
    enum JISCODE_KIND   // コード種別
    {
        JIS_ASCII = 0,
        JIS_8BIT,
        JIS_ZENKAKU
    } tJisKind = JIS_ASCII;

    if ( nLength == 0 )
    {
        return strResult;
    }
    // 文字列の領域確保
    // (1文字=エスケープ・シーケンス+JISコードを考慮し多めに設定)
    lpszResult = strResult.GetBufferSetLength( nLength * 4 + 1 );
    
    for ( nStrPos = 0; nStrPos < nLength; nStrPos++ )
    {
        byHiByte = _strText.GetAt( nStrPos );

        // Shift-JIS全角文字列の上位バイトである場合
        if ( _ismbblead( static_cast< unsigned int >( byHiByte ) ) )
        {
            byLowByte = _strText.GetAt( nStrPos + 1 );

            // Shift-JIS全角文字列の下位バイトである場合
            if ( _ismbbtrail( static_cast< unsigned int >( byLowByte ) ) )
            {
                // Shift-JISコードを取得
                wCode = MAKEWORD( byLowByte, byHiByte );
                // JISコードに変換
                wCode = static_cast< WORD >( _mbcjmstojis( static_cast< 
unsigned int >( wCode ) ) );

                if ( tJisKind != JIS_ZENKAKU )
                {
                    // エスケープ・シーケンスの付加
                    *lpszResult++ = 0x1B;
                    *lpszResult++ = 0x24;
                    *lpszResult++ = 0x42;

                    tJisKind = JIS_ZENKAKU;
                }
                // JISコードを設定
                *lpszResult++ = HIBYTE( wCode );
                *lpszResult++ = LOBYTE( wCode );
                
                nStrPos++;
                continue;
            }
        }
        // 半角カタカナである場合
        else if ( _ismbbkana( static_cast< unsigned int >( byHiByte ) ) )
        {
            if ( tJisKind != JIS_8BIT )
            {
                // エスケープ・シーケンスの付加
                *lpszResult++ = 0x1B;
                *lpszResult++ = 0x28;
                *lpszResult++ = 0x49;

                tJisKind = JIS_8BIT;
            }
            // そのまま設定
            *lpszResult++ = byHiByte;

            continue;
        }

        if ( tJisKind != JIS_ASCII )
        {
            // エスケープ・シーケンスの付加
            *lpszResult++ = 0x1B;
            *lpszResult++ = 0x28;
            *lpszResult++ = 0x4A;

            tJisKind = JIS_ASCII;
        }
        // その他の文字はそのまま設定
        *lpszResult++ = byHiByte;
    }
    // 終端文字を設定
    *lpszResult = '\0';
    // 文字列の確定
    strResult.ReleaseBuffer();
    
    return strResult;
}

Blue 2005/03/22(火) 15:22:31
>        // Shift-JIS全角文字列の上位バイトである場合
>        if ( _ismbblead( static_cast< unsigned int >( byHiByte ) ) )
>        {
>            byLowByte = _strText.GetAt( nStrPos + 1 );

(省略)

>           continue;
>       }

修正
    2バイト文字の先行バイトで文字列が終わっている場合、下位バイト取得時のGetAt
で不正アクセスになるので、
    最後の文字であるかの判定分をそのまえに追加するように変更。

        // Shift-JIS全角文字列の上位バイトである場合
        if ( _ismbblead( static_cast< unsigned int >( byHiByte ) ) )
        {
            // 最後の文字でない場合
            if ( nStrPos != nLength - 1 )                  // (追加行)
            {                                              // (追加行)
                byLowByte = _strText.GetAt( nStrPos + 1 );
                
(省略)
                
                continue;
            }                                              // (追加行)
        }

古いスレッドには追加発言できません。