HSP3 プログラミングの基礎W | |
(5) 文字列の比較
HSP3には、文字列の長さを得るstrlenなど、文字列を処理する命令や関数がいろいろと用意されている。しかし、HSP3の標準命令には文字列を比較する関数がない。ここでは、文字列を比較する関数の作成を目標とする。
最終的には、文字列の比較を利用して文字列のソートを作成する予定であるが、文字列のソートについては、拡張プラグインの「HSPDA.DLL」(HSP3に同梱)にsortstr命令として用意されている。
◎ 文字コード
文字には1文字ずつ番号が割り当てられており、この番号のことを文字コードという。例えば、半角英数字には次のような文字コードが割り当てられている。
文字列を1文字ずつ表示する。
moji = "0123456789" repeat strlen(moji) ;文字数分繰り返す mes strmid(moji, cnt, 1) ;1文字ずつ表示 loop stop
0 1 2 3 4 5 6 7 8 9 |
1行に1文字ずつ表示される。
関数strlenは、文字列の字数を取得する関数である。文字数分だけ繰り返している。
関数strmidは、文字列の一部分を取り出す関数である。「strmid(moji, cnt, 1)」で変数mojiの先頭からシステム変数cnt番目の1文字を取り出す。
取り出した1文字ごとの文字コードを表示する。
moji = "0123456789" repeat strlen(moji) ;文字数分繰り返す m1 = strmid(moji, cnt, 1) ;1文字取り出す cnvstow c1, m1 ;文字コードに変換 mes m1 + " : " + strf("%X", c1) + " / " + c1 loop stop
0:30 / 48 1:31 / 49 2:32 / 50 3:33 / 51 4:34 / 52 5:35 / 53 6:36 / 54 7:37 / 55 8:38 / 56 9:39 / 57 |
1行に1文字ずつ文字と文字コードが表示される。
cnvstow命令は、文字コード(Unicode)に変換する命令である。「cnvstow c1, m1」で文字m1を文字コードに変換して、結果を変数c1に格納する。
変数c1には文字コードが格納されているが、mes命令でそのまま表示すると10進数で表示される。16進数でも表示したいので、strf関数で変数c1の値を16進数に変換している。
いろいろな文字に変更して実行してみよ。また、漢字(全角文字)ではどのような結果になるか。
1行目を「moji = "あい亜伊"」に変更する。
全角文字は2バイトなので1つの文字について2つずつ文字コードが表示される。しかし、実行結果のように意味のある文字コードには見えない。
ここで、一つポイントとなるのは、「全角文字の1バイト目をcnvstow命令で文字コードに変換すると0になる」ということである。全角文字か半角文字かを区別するのには利用できそうである。
次のようにして、全角文字の文字コードを表示してみよ。
m1 = "あ"
cnvstow c1, m1 ;文字コードに変換
mes m1 + " : " + strf("%X", c1) + "
/ " + c1
stop
「あ : 3042 / 12354」と表示される。
全角文字は2バイトを一度にcnvstow命令で変換すると正しい文字コードに変換される。
◆ 文字列比較命令(str_comp)作成
半角(1バイト)文字、全角(2バイト)文字、どちらでも次のようにプログラムすると文字コードが変数mc1に取り出せる。
cnvstow mc1, strmid(mj1, pm1, 1) ;1バイトを文字コード変換
if mc1 = 0 : cnvstow mc1, strmid(mj1, pm1, 2) : pm1 += 1 ;2バイトを文字コード変換
文字コードを取り出すことができれば、2つの文字列を先頭から順に文字コードで比較していくだけで文字列比較命令ができる。
文字列を比較する命令str_compを作成する。
#module ;---------- #defcfunc str_comp str moji1, str moji2 ; ;str_comp(moji1, moji2) ; moji1, moji2=文字列 ; 返却値=int 比較結果 0=moji1=moji2 1=moji1>moji2 -1=moji1<moji2 ; mj1 = moji1 : mj2 = moji2 pm1 = 0 : pm2 = 0 repeat ;文字列1の処理 cnvstow mc1, strmid(mj1, pm1, 1) ;1バイトを文字コード変換 if mc1 = 0 : cnvstow mc1, strmid(mj1, pm1, 2) : pm1 += 1 ;2バイトを文字コード変換 ;文字列2の処理 cnvstow mc2, strmid(mj2, pm2, 1) ;1バイトを文字コード変換 if mc2 = 0 : cnvstow mc2, strmid(mj2, pm2, 2) : pm2 += 1 ;2バイトを文字コード変換 ;文字コードの比較 if mc1 > mc2 : res = 1 : break ;※1 if mc1 < mc2 : res = -1 : break ;※2 if mc1 = 0 and mc2 = 0 : res = 0 : break ;※3 pm1 += 1 : pm2 += 1 wait 1 loop return res #global ;テスト用プログラム a = "あいうえ" : b = "あいうえ" rcmp = str_comp(a, b) : gosub *kekka b = "あいう" rcmp = str_comp(a, b) : gosub *kekka b = "あうえ" rcmp = str_comp(a, b) : gosub *kekka b = "zあうえ" rcmp = str_comp(a, b) : gosub *kekka stop *kekka if rcmp = 0 : mes a + " = " + b if rcmp = 1 : mes a + " > " + b if rcmp = -1: mes a + " < " + b return
あいうえ = あいうえ あいうえ > あいう あいうえ < あうえ あいうえ > zあうえ |
比較した文字が違えば、※1、※2の比較でループを抜けて処理が終わる。
比較した文字が一致している間はループを繰り返すが、比較する文字がなくなれば文字コードmc1, mc2は両方とも0になるので、※3で判定してループを抜けるようにしている。
2006 © Hiroshi Masuda |