|
|
2007/1/24(Wed) 01:20:55|NO.5062
メモ帳の検索機能を作ってたものです。instrで文字列を検索し始める位置を
文字インデックス値からバイト数に変換してInstrで利用していたのですが、
その変換目的に作った関数がどうしてもうまく動いてくれません。
どなたかご教授お願いいたします。
#module
//指定した変数の文字インデックスをバイト位置に変換
//p1: 文字インデックス値を取得する文字列型変数
//p2: 変換したい文字インデックス値
#defcfunc StrIndexToByte var p1, int p2
sdim s1,strlen(p1)
memcpy s1,p1,p2,0,0 //指定した位置までの文字数を取得
s2=0
repeat p2
s3=peek(s1,cnt)
if ((s3>=$81)&(s3<=$9f))|((s3>=$e0)&(s3<=$fc))=1{
s2+2
}else{
if cnt\2 {
s2+2
} else {
s2+
}
}
loop
return s2
#global
editstr={"
クリスマス
kurisumasu
"}
mesbox editstr,640,480
s2=objinfo(0,2)
*mainloop
sendmsg s2, $b0, 0, varptr(s5)
title "文字インデックス値 = "+s5+" 文字目 バイト値 = "+StrIndexToByte(editstr,s5)+" byte"
wait 10
goto *mainloop
stop
|
|
2007/1/24(Wed) 02:04:19|NO.5065
これでどうでしょうか?
repeat p2
s3=peek(s1,cnt)
if ((s3>=$81)&(s3<=$9f))|((s3>=$e0)&(s3<=$fc))=1{
s2+2
continue (cnt + 2)
}else{
;if cnt\2 {
; s2+2
;} else {
s2+
;}
}
loop
|
|
2007/1/24(Wed) 03:04:43|NO.5067
恥ずかしながら、何をなさりたいのか掴み切れませんが
もしかしたら、
下記のような動作を想定しているのでしょうか?
違っていたら申し訳ございません。
#module
//指定した変数の文字インデックスをバイト位置に変換
//p1: 文字インデックス値を取得する文字列型変数
//p2: 変換したい文字インデックス値
#defcfunc StrIndexToByte var p1, int p2
sdim s1,strlen(p1)
memcpy s1,p1,p2,0,0 //指定した位置までの文字数を取得
s2=0
flag=0
repeat p2
s3=peek(s1,cnt)
if flag=1:flag=0:continue
if ((s3>=$81)&(s3<=$9f))|((s3>=$e0)&(s3<=$fc))=1{
s2+:flag=1
}
else{
s2+
}
loop
return s2
#global
editstr={"
クリスマス
kurisumasu
"}
mesbox editstr,640,480
s2=objinfo(0,2)
*mainloop
sendmsg s2, $b0, 0, varptr(s5)
title "文字インデックス値 = "+s5+" バイト目 "+StrIndexToByte(editstr,s5)+" 文字目"
wait 20
goto *mainloop
stop
|
|
2007/1/24(Wed) 08:29:44|NO.5070
言葉足らずで申し訳けありません。
メッセージボックス左上から始まって 何文字目 という値を
その文字位置までのバイト数に変換したいのです。
StrIndexToByte(文字列型変数,文字位置)
「あああああ」
↑これだと5文字ですが、この関数で変換すると 10byte になります。
「あああAAA」
↑この場合は6文字ですが、同じように変換すると9byte になります。
提示したスクリプトでは titleバーを利用してデバックしてます。
|
|
2007/1/24(Wed) 10:27:25|NO.5071
> ↑これだと5文字ですが、この関数で変換すると 10byte になります。
(中略)
> ↑この場合は6文字ですが、同じように変換すると9byte になります。
ん?SJISのままなら合ってますよね。
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF
00 | 82 A0 82 A0 82 A0 82 A0 82 A0 00 00 00 00 00 00 | あああああ......
01 | 82 A0 82 A0 82 A0 41 41 41 00 00 00 00 00 00 00 | あああAAA.......
なお、SJISが日本語の文字コードとしては一番サイズが小さく、JISやEUC-JP,Unicode/UTF-8
などはサイズがSJISよりも日本語のbyte数は大きくなります。
|
|
2007/1/24(Wed) 12:07:07|NO.5073
文字コードはS-JISのままです。
今いろいろとやっておりますが、うまく動きません。
2byte文字と認識するはずのところが1byteしか認識されてなかったり
peek命令自体キャレットからずれている可能性があります。><
|
|
2007/1/24(Wed) 13:24:44|NO.5074
なんかよくわかりませんが解決いたしました^^;
いったいなにがいけなかったのやら・・・。
モジュール内では2byte文字の先頭なら2byteジャンプし、
1byte文字なら1byteジャンプする仕組みになっています。
#module
//指定した変数の文字インデックスをバイト位置に変換
//p1: 文字インデックス値を取得する文字列型変数
//p2: 変換したい文字インデックス値
#defcfunc StrIndexToByte var p1, int p2
s2=0 //byteカウント
repeat p2
s1=peek(p1,s2)
if ((s1>=$81)&(s1<=$9f))|((s1>=$e0)&(s1<=$fc)){
s2+2
}else{
s2+
}
loop
return s2
#global
bgscr 2,100,100,4,0,0
screen 0,640,480,200,200
editstr={"
aクリスマス
kurisumasu
"}
mesbox editstr,640,480
s2=objinfo(0,2)
*mainloop
sendmsg s2, $b0, 0, varptr(s5)
title "( 文字インデックス値 = "+s5+" 文字目 ) → 変換 → ( バイト値 "+StrIndexToByte(editstr,s5)+" byte )"
wait 10
goto *mainloop
stop
|
|
2007/1/24(Wed) 14:38:01|NO.5075
どういう動作をして欲しいのかがよく分からないのでちゃんとした回答が得られないと
思います。
とりあえず、SJISのコードをすべて網羅しているわけではありませんが以下は何byte目が
何の文字なのかを表示するサンプルです。
(実際には記号などもあるのでもっとややこしいです)
#module
#defcfunc _len int p1, int p2
return strf("インデックス: %" + strlen("" + p1) + "d byte", p2)
#global
; SJIS の範囲かを判断(不完全)
#define ctype SJIS_FULLSPACE(%1, %2) (%1 = 0x81 & %2 = 0x40)
#define ctype SJIS_FULLDIGIT(%1, %2) ((%1 = 0x82) & (%2 >= 0x4f & %2 <= 0x58))
#define ctype SJIS_FULLUCHAR(%1, %2) ((%1 = 0x82) & (%2 >= 0x60 & %2 <= 0x79))
#define ctype SJIS_FULLLCHAR(%1, %2) ((%1 = 0x82) & (%2 >= 0x81 & %2 <= 0x9a))
#define ctype SJIS_FULLACHAR(%1, %2) ( \
SJIS_FULLUCHAR(%1, %2) | \
SJIS_FULLLCHAR(%1, %2) \
)
#define ctype SJIS_HIRA(%1, %2) ((%1 = 0x82) & (%2 >= 0x9f & %2 <= 0xf1))
#define ctype SJIS_HIRAEX(%1, %2) ( \
SJIS_HIRA(%1, %2) | \
( \
%1 = 81 & \
(%2 = 0x4a | %2 = 0x4b | 0x54 | 0x55) \
) \
)
#define ctype SJIS_KATA(%1, %2) ((%1 = 0x83) & (%2 >= 0x40 & %2 <= 0x96))
#define ctype SJIS_KATAEX(%1, %2) ( \
SJIS_KATA(%1, %2) | \
( \
%1 = 81 & \
(%2 = 0x45 | %2 = 0x5b | 0x52 | 0x53) \
) \
)
#define ctype SJIS_RANGE(%1, %2) ( \
SJIS_FULLSPACE(%1, %2) | \
SJIS_FULLDIGIT(%1, %2) | \
SJIS_FULLUCHAR(%1, %2) | \
SJIS_FULLLCHAR(%1, %2) | \
SJIS_FULLACHAR(%1, %2) | \
SJIS_HIRA(%1, %2) | \
SJIS_HIRAEX(%1, %2) | \
SJIS_KATA(%1, %2) | \
SJIS_KATAEX(%1, %2) \
)
editstr={"
クリスマス
kurisumasu
"}
len = strlen(editstr)
for i, 0, len, 1
p = peek(editstr, i), peek(editstr, i + 1)
if SJIS_RANGE(p, p(1)) {
; SJIS の全角文字
mes _len(len, i) + strf(" / 文字: %c", p) + strf("%c", p(1))
i++
} else : if (p >= 'A' & p <= 'Z') | (p >= 'a' & p <= 'z') {
; 半角文字
mes _len(len, i) + strf(" / 文字: %c", peek(p))
} else : if (p(0) = '\n' & p(1) = 0x0a) | (p = '\n') | (p = 0x0a) {
; 改行文字
mes _len(len, i) + " / 文字: \\n"
if (p(0) = '\n' & p(1) = 0x0a) {
i++
}
} else : if p = '\t' {
; タブ文字
mes _len(len, i) + " / 文字: \\t"
} else {
}
if p(1) = 0 {
; NULL 文字
i++
mes _len(len, i) + " / 文字: \\0"
}
next
stop
文字コードの範囲を調べるには以下をご参照ください。
http://www.din.or.jp/~ohzaki/perl.htm#Character
| |
|