antenn-a
company profile

MFC航海日記 三十九日(マルチバイト文字列の大・小文字変換)

さて、今回の開発もいよいよ大詰めである。 今回は文字列の大・小文字変換について解説する。

ここで、気を付けなければならないのは「我々は日本人である」と言う事だ。 「はぁ?何言ってるの?」となっている人!それが間違いです。

prev


日本人ならば、当然日本語を用いているはずである。 日本語は・・・そう!2バイト使うのである。 英語ならば1バイトで済むところを日本語は2バイト使わないと一文字があらわせないのである。

ここで、関数を色々と調べてみると、それらしきものが見つかった。

_mbsupr( ( unsigned char* )Buffer );
_mbslwr( ( unsigned char* )Buffer );

の2つである。

上の関数が、文字列すべてを大文字に変える関数で、下が小文字に変換する関数である。 先頭についている「mb」はマルチバイトの略だと思うのだが、つまり複数バイトに対応した、文字列の大・小文字変換関数である。

prev


これで、出来た!と思ったら、もう一つ問題があった。

今回のソフトは「単語の先頭だけ大文字に変換」という機能がある。

これは、「this is a test」を「This Is A Test」とするもので、文字列全部を大文字に変えてはいけないのである。

prev


「aiueo」ならば、ポインタで追いかけると、「a, b, c, d, e」となるはずである。 これを大文字に変えたい場合は、
void ToBig( char* str )
{
    char*    p;
    int      i;
    
    p = str;
    for( i = 0; i < strlen( str ); i++ ){
        *p = toupper( *p );
        p++;
    }
}
とすればよい。

しかし、「あいうえお」の場合、ポインタで追いかけると一文字2バイトであるので、
1.「あ」の1バイト目
2.「あ」の2バイト目
3.「い」の1バイト目
4.「い」の2バイト目


となっていく。 この場合に限っては、大文字に変換する部分が無いわけである。

prev


toupper() はおりこうさんなので、変換できないものは変換しないのであるが、問題は2バイト目である。

2バイト文字の場合、1バイト目に2バイト文字であるコードが書かれ、2バイト目に1バイト目とセットになるような「文字」が来る。

結局1バイト目と、2バイト目の両方を比べて文字を算出するわけだが、困った事に2バイト目に「アルファベット」が来てしまう可能性があるのである。

prev


とすると当然困るわけで、2バイト目に「a」があったとすると、さっきの関数を呼んだ場合2バイト目が「A」に変わってしまい、算出される文字が違う文字になってしまうのである。

これを回避する為には、ポインタで追いかけていった時にその文字が「2バイトコードの第一バイト目かどうか」を見極める必要がある。

筆者が、Borland C++ を用いていた頃は「iskanji( int c )」なる関数があり、引数に渡す文字が2バイトコードの第一バイト目だった場合は TRUE を返し、そうでない場合は FALSE を返す関数があった。

これと同じような関数が Visual C++ にもあるはずである!と思った私は色々調べた。

結果、「iskanji()」と同じ内容の関数が見つかった。

名前は、「_ismbblead()」という関数である。

prev


この関数を使えば、「単語の先頭だけ大文字に変換」がすぐにできた。
void WordUper()
{
    char* p;

    p = Buffer;

    //先頭は大文字に変換
    if( _ismbblead( *p ) == 0 )
        *p = toupper( *p );

    while( *p != '\0' ){
        if( *p == ' ' &&  _ismbblead( *( p + 1 ) ) == 0 ){
            p++;
            *p = toupper( *p );
        }
        p++;
    }
}
このようなコードになる。

prev


ファイルの排他制御と同じで、文字列のマルチバイト処理も非常に重要でかつ面倒な処理である。 読者の方も気を付けて欲しい。


antenn-a

prev next


antenn-a