〜 テキスト 〜
半角英数を全角に変換

HSPの文字コードはシフトJISです。
シフトJISの半角英字Aは65、Bは66、Cは67…Zは90が割り振られています。
また、小文字半角aは97、bは98、cは99…zは122が割り振られています。
一方の全角英字Aは24706、Bは24962、Cは25218…Zは31106です。
全角小文字は33154から始まり、bは33410、cは33666…zは39554となってます。
一見すると、全角はバラバラのように思えますが、256ずつ規則的に増えて行っています。
これは2バイト文字の上位バイト(下から数えて9ビット目)が1ずつ増えて行っているためです。
数値も同様に、半角が0は49、1は50、2は51…9は57となっているのに対し、
全角0は20610、1は20866、2は21122…9は22658となっています。
この法則さえ分かってしまえば、変換することは容易ですが、半角と全角は文字幅が変わってしまいます。
特に、半角から全角への変換は、元の文字列サイズよりも増加するわけですから注意が必要です。
全角文字へ変換する際、最大で文字サイズが元の2倍になります。
エラーにならないよう制御してますが、HSP2サンプルのように格納先変数は大きめに確保しましょう。
API関数LCMapStringを用いて変換したい方は、コチラを利用してみてください。
	

wordchk 対象変数, 位置
対象変数判別したい文字列の入った変数を指定する。
statに-1(範囲外)、0(半角)、1(全角)のいずれかがセットされる。
位置指定変数の位置をバイト単位で指定する。

getvarsize 変数
変数指定変数のサイズがstatにセットされる。

zenkaku 書込先変数, 読込元変数
書込先変数変換したテキストを代入する文字列型の変数を指定する。
statに-1(範囲外)、0(半角)、1(全角1バイト目)、2(全角2バイト目)のいずれかがセットされる。
内部でwordchk命令とgetvarsize命令を使用しているため、
zenkaku命令の前にwordchk命令とgetvarsize命令を定義すること!
読込元変数変換したい文字列型の変数を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#module
#deffunc wordchk val, int
	mref txt, 24 : mref ichi, 1
	mref stt, 64
	peek chk, txt, ichi
	if chk = 0 : stt = -1 : return // 範囲外
	if (chk > 128 & (chk < 160)) | (chk > 223) : stt = 1 : else : stt = 0 // 1byte=0 2byte=1
	return

#deffunc getvarsize val
	mref pval, 1024             // PVAL構造体
	mref stt, 64                // stat
	stt = 4
	repeat 4, 2
		if pval.cnt = 0 : break
		stt = stt * pval.cnt
	loop
	return

#deffunc zenkaku val, val
	mref rstr, 24 : mref string, 25
	strlen i, string
	sample = "09AZaz"              // 半角変換対象の代表
	sa = 31, 31, 32                 // 全角と半角のコード差(数値, 英大字, 英小字)
	getvarsize rstr : size = stat   // 保存先変数サイズを取得
	memset rstr, , size
	repeat i
		wordchk string, cnt
		if (stat = -1) || (type < 0) || (type > 1) {
			break
		} else {
			strlen i, rstr
			if i + stat + 1 >= size : break // オーバーフロー防止
			// 対象文字が全角
			if stat {
			  wpeek chk, string, cnt
			  wpoke rstr, i, chk
			  // 2バイト進める
			  continue cnt + 2
			// 対象文字が半角
			} else {
			  peek chk, string, cnt
			  repeat 3
			    // 変換対象範囲内なら変換
			    peek compare.0, sample, cnt * 2 + 0
			    peek compare.1, sample, cnt * 2 + 1
			    if (chk >= compare) && (chk <= compare.1) {
			      poke rstr, i + 0, 130
			      poke rstr, i + 1, chk + sa.cnt
			      chk = -1 // 変換したことを示すフラグ
			      break
			    }
			  loop
			  if chk ! -1 : poke rstr, i, chk
			}
		}
	loop
	return
#global

	sdim data, 128, 2 // 代入先変数は大きめに確保しておくこと!
	data = "ABCabc012あいうABCabc012わをんxyz890XYZXYZ890xyz"
	mes "元の文字列 " + data
	zenkaku data.1, data.0
	mes "全角へ変換 " + data.1
	stop

結果 = wordchk(対象変数, 位置)
結果-1(範囲外)、0(半角)、1(全角)のいずれかがセットされる。
対象変数判別したい文字列の入った変数を指定する。
位置指定変数の位置をバイト単位で指定する。

結果 = zenkaku(変数)
結果取り出した文字列の格納先を指定する。
内部でwordchk命令を使用しているため、bytechange命令の前にwordchk命令を定義すること!
変数変換対象の文字列が格納されている変数を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#module
#defcfunc wordchk var s, int ichi
	if ichi < 0 : return -1 // 範囲外
	chk = peek(s, ichi)
	if (chk > 128 & chk < 160) | chk > 223 : return 1 // 2byte=1
	if chk = 0 : return -1 : else : return 0            // 1byte=0 範囲外=-1

#defcfunc zenkaku var string, local rstr, local sample, local sa
	sdim rstr, strlen(string) * 2 // 元のサイズの2倍分を確保
	sample = "09AZaz"             // 半角変換対象の代表
	sa = 31, 31, 32               // 全角と半角のコード差(数値, 英大字, 英小字)
	repeat strlen(string)
		if wordchk(string, cnt) = -1 || type < 0 || type > 1 {
			break
		} else {
			// 対象文字が全角
			if stat {
			  wpoke rstr, strlen(rstr), wpeek(string, cnt)
			  // 2バイト進める
			  continue cnt + 2
			// 対象文字が半角
			} else {
			  chk = peek(string, cnt)
			  repeat length(sa)
			    // 変換対象範囲内なら変換
			    if chk >= peek(sample, cnt * 2) && chk <= peek(sample, cnt * 2 + 1) {
			      poke rstr, strlen(rstr), 130
			      poke rstr, strlen(rstr), chk + sa.cnt
			      chk = -1 // 変換したことを示すフラグ
			      break
			    }
			  loop
			  if chk ! -1 : poke rstr, strlen(rstr), chk
			}
		}
	loop
	return rstr
#global

	sdim data, 128
	data = "ABCabc012あいうABCabc012わをんxyz890XYZXYZ890xyz"
	mes "元の文字列 " + data
	mes "全角へ変換 " + zenkaku(data) // 全角英数へ