プログラム講座 中級編16

- 全角数値/アルファベットから半角へのコード変換 -

 中級編16です。今回は「全角数値/アルファベットから半角へのコード変換」を行います。2バイトコードの処理は、今までに行った改行コードの変換とは異なる配慮が必要になる場合があります。今回は最も単純な全角文字から半角文字への変換について勉強しましょう。




変換する文字のコード範囲
 変換するテキストは「シフトJIS」コードで記述してある事が大前提です。EUC, JIS, Unicodeでは正常に動作しません。Macで文章を作成したりすれば通常シフトJISになりますので、特に心配することもないでしょう。変換する文字は以下の通りです。表中の&h〜は「16進数」を表しています。

変換元文字列シフトJISコード変換後のアスキーコード
0123456789&h824F〜&h8258&h30〜&h39
全角アルファベット大文字(ABCD)&h8260〜&h8279&h41〜&h5A
全角アルファベット小文字(abcd)&h8281〜&h829A&h61〜&h7A

 上記の表のように3グループにわけて判定して変換するのが楽そうです。幸い規則性がありますので単純な引き算と足し算で変換できます。



シフトJISのコードかどうかをチェックするには?
 次に変換するテキストの文字が2バイトコードかどうかを調べなければなりません。シフトJISのコード範囲は以下の表のようになっています。

1バイト目&h81〜&h9F, &hE0〜&hFC
2バイト目&h40〜&h7E, &h80〜&hFC

 まず1バイト目を調べて2バイトコードかどうかをチェックします。2バイトコードであれば1バイト目が&h82かどうか調べます。&h82であれば全角数値か、アルファベットかどうかを調べて変換していきます。
 文字のアスキーコードを調べるには

a = ASC(moji$)

 のようにASC命令を使います。この命令を使えば文字をアスキーコードに変換してくれます。この逆を行うのはCHR$です。
 ファイルからの読み込み、書き込みは1バイト単位で行います。今までの講座でメモリ確保して高速に変換するのもよいでしょう。用途に合わせていろいろ改良してみて下さい。



終わりに
 今回はリクエスト(?)に答えてみました。日本語処理は結構面倒ですが、各種文字コードへの変換についても解説しようと思います。



今回のプログラムリスト
' ' "全角の数値およびアルファベットのみを半角にするプログラム" ' OUTPUT FILE "toHankaku": ' "作成されるアプリケーション名 ' "ファイルを開いてデータを変換する" LOCAL FN openFile filename$ = FILES$(_fOpen,"TEXT",,vRefnum%) IF filename$="" THEN EXIT FN f$ = filename$+".txt" savefile$ = FILES$(_fSave,"保存ファイル名:",f$,vRefnum2%) OPEN "I",#1,filename$,,vRefnum% DEF OPEN "TEXTttxt" OPEN "O",#2,savefile$,,vRefnum2% PRINT "変換中です..." WHILE NOT EOF(1) READ #1,a$;1 a = ASC(a$): ' "アスキーコードを算出します" '"まずシフトJIS(2バイトコード)かどうか調べる LONG IF (a >= &h81 AND a <= &h9f ) OR ( a>= &hE0 AND a <= &hFC) READ #1,b$;1: ' "1バイト目を読み込む" b = ASC(b$) ' "全角数値、全角アルファベットは82で始まるコード領域にある" LONG IF a = &h82 c$ = "" ' "--------- 全角の数値かどうかを調べる" IF b >= &h4F AND b <= &h58 THEN c$ = CHR$(b - &h4F + &h30):WRITE #2,c$;1 ' "--------- 全角大文字アルファベットかどうかを調べる" IF b >= &h60 AND b <= &h79 THEN c$=CHR$(b - &h60 + &H41):WRITE #2,c$;1 ' "--------- 全角小文字アルファベットかどうかを調べる" IF b >= &h81 AND b <= &h9A THEN c$=CHR$(b - &h81 + &H61):WRITE #2,c$;1 ' "--------- 該当しない場合は2バイト書き込む" IF c$="" THEN WRITE #2,a$;1,b$;1 XELSE WRITE #2,a$;1,b$;1 END IF XELSE WRITE #2,a$;1: ' "1バイト書き込む" END IF WEND CLOSE #1,#2 PRINT "変換は終了しました" END FN ' "メニュー構築" LOCAL FN initMenu 'APPLE MENU "toHnakakuについて..." 'File Menu MENU 1,0,_enable,"ファイル" MENU 1,1,_enable,"/O開 く..." MENU 1,2,_enable,";" MENU 1,3,_enable,"/Q終 了" END FN ' "メニュー分岐処理" LOCAL FN doMenu menuID = MENU(_menuID): ' "どのメニューバー項目かな?" itemID = MENU(_itemID): ' "選択項目は何かな?" SELECT menuID CASE 1 : ' File... Menu SELECT itemID CASE 1: ' Open File... FN openFile CASE 3: ' Quit Menu... END END SELECT END SELECT MENU END FN ON MENU FN doMenu FN initMenu WINDOW OFF WINDOW #1,"状 況",(44,50)-(44+340,50+240),_dialogMovable WHILE 1 HANDLEEVENTS WEND