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 

 

 

inserted by FC2 system