|
さて、今回の開発もいよいよ大詰めである。
今回は文字列の大・小文字変換について解説する。
ここで、気を付けなければならないのは「我々は日本人である」と言う事だ。 「はぁ?何言ってるの?」となっている人!それが間違いです。 |
|
|
|
日本人ならば、当然日本語を用いているはずである。 日本語は・・・そう!2バイト使うのである。 英語ならば1バイトで済むところを日本語は2バイト使わないと一文字があらわせないのである。 ここで、関数を色々と調べてみると、それらしきものが見つかった。 _mbsupr( ( unsigned char* )Buffer ); _mbslwr( ( unsigned char* )Buffer ); の2つである。 上の関数が、文字列すべてを大文字に変える関数で、下が小文字に変換する関数である。 先頭についている「mb」はマルチバイトの略だと思うのだが、つまり複数バイトに対応した、文字列の大・小文字変換関数である。 |
|
|
|
これで、出来た!と思ったら、もう一つ問題があった。 今回のソフトは「単語の先頭だけ大文字に変換」という機能がある。 これは、「this is a test」を「This Is A Test」とするもので、文字列全部を大文字に変えてはいけないのである。 |
|
|
|
「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バイト目 となっていく。 この場合に限っては、大文字に変換する部分が無いわけである。 |
|
|
|
toupper() はおりこうさんなので、変換できないものは変換しないのであるが、問題は2バイト目である。 2バイト文字の場合、1バイト目に2バイト文字であるコードが書かれ、2バイト目に1バイト目とセットになるような「文字」が来る。 結局1バイト目と、2バイト目の両方を比べて文字を算出するわけだが、困った事に2バイト目に「アルファベット」が来てしまう可能性があるのである。 |
|
|
|
とすると当然困るわけで、2バイト目に「a」があったとすると、さっきの関数を呼んだ場合2バイト目が「A」に変わってしまい、算出される文字が違う文字になってしまうのである。 これを回避する為には、ポインタで追いかけていった時にその文字が「2バイトコードの第一バイト目かどうか」を見極める必要がある。 筆者が、Borland C++ を用いていた頃は「iskanji( int c )」なる関数があり、引数に渡す文字が2バイトコードの第一バイト目だった場合は TRUE を返し、そうでない場合は FALSE を返す関数があった。 これと同じような関数が Visual C++ にもあるはずである!と思った私は色々調べた。 結果、「iskanji()」と同じ内容の関数が見つかった。 名前は、「_ismbblead()」という関数である。 |
|
|
|
この関数を使えば、「単語の先頭だけ大文字に変換」がすぐにできた。
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++;
}
}
このようなコードになる。
|
|
|
|
ファイルの排他制御と同じで、文字列のマルチバイト処理も非常に重要でかつ面倒な処理である。 読者の方も気を付けて欲しい。 |