HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2007
0124
As文字インデックス値 から バイト値 への変換8解決


As

リンク

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



この記事に返信する


naznyark

リンク

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



Irisawa

リンク

2007/1/24(Wed) 02:16:36|NO.5066

意味がよく分からなかったのですが、要はUnicode文字のようにbyteに関係なく
カーソル位置が何文字目かということを検索したいということでしょうか。
サンプルを実行してみた限りでは正常に動作しているようなのですが、どこが正常に
動作していないのかもう少し詳しく説明していただけないでしょうか。

もし、改行が入ると2byteとして認識されるというのならこれはWinの改行コードの
仕様です。
Winの改行コードはCRLF(0x0d0x0a)で2byteです。

http://ja.wikipedia.org/wiki/%E6%94%B9%E8%A1%8C%E3%82%B3%E3%83%BC%E3%83%89



kanzaki

リンク

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



As

リンク

2007/1/24(Wed) 08:29:44|NO.5070

言葉足らずで申し訳けありません。

メッセージボックス左上から始まって 何文字目 という値を

その文字位置までのバイト数に変換したいのです。




StrIndexToByte(文字列型変数,文字位置)



「あああああ」
↑これだと5文字ですが、この関数で変換すると 10byte になります。

「あああAAA」
↑この場合は6文字ですが、同じように変換すると9byte になります。


提示したスクリプトでは titleバーを利用してデバックしてます。



Irisawa

リンク

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数は大きくなります。



As

リンク

2007/1/24(Wed) 12:07:07|NO.5073

文字コードはS-JISのままです。
今いろいろとやっておりますが、うまく動きません。

2byte文字と認識するはずのところが1byteしか認識されてなかったり
peek命令自体キャレットからずれている可能性があります。><



As

リンク

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



Irisawa

リンク

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



ONION software Copyright 1997-2021(c) All rights reserved.