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


HSPTV!掲示板


未解決 解決 停止 削除要請

2010
0214
shironなぜかループしてしまうのですが。3解決


shiron

リンク

2010/2/14(Sun) 14:16:49|NO.30602

1byteと2byteの判定でいい方法を見つけたのでプログラムを組んでいます。
改行も扱いたくていくつか方法を試したのですが、改行自体はできるけれど
文章が終わるところで終了してくれず、ループしてしまうといった状況です。
問題の箇所は95行目あたりからです。
ソースが長くてすみません。よろしくお願いします。

//---バイト数チェックモジュール #module #deffunc biteload str chk s = chk notesel s max = noteinfo(1) return #deffunc chkbite int chk_place//調べる文字,インディエット if chk_place >= max{//範囲外の場所ははじく chk_s = "" s_length = 0 return } getstr chk_s,s,chk_place,,1//文字を取得 s_length = strlen(chk_s)//バイト数を取得 ; if s_length = 0:return -1 ; if s_length = 1:return 1 ; if s_length = 2:return 2 return #defcfunc biteinfo int info_prm if info_prm = 0{//バイト数 if s_length = 0:return -1 if s_length = 1:return 1 if s_length = 2:return 2 } if info_prm = 1 : return chk_s//調べた文字 if info_prm = 2{//文章全体の長さ infobreak num = 0//調べる場所 str_num = 0//文字数 repeat chkbite num bite = biteinfo(0) if bite = -1:break num += bite str_num ++ loop infoback return str_num } if info_prm = 3{ return chk_place//現在の初めからのバイト数 } return -1 #deffunc infobreak//パラメータを一時保持します。 rp0 = s_length rp1 = chk_s rp2 = chk_place return #deffunc infoback//パラメータを戻します。 s_length = rp0 chk_s = rp1 chk_place = rp2 return #defcfunc chklen num = 0//調べる場所 str_num = 0//文字数 repeat chkbite num bite = biteinfo(0) if bite = -1:break num += bite str_num ++ loop return str_num #global //-----------モジュール終了 /*notesel a noteload "test.txt" */ a = "HELLO!\nHELLO\nこんにちは!\nコンニチハ\nコンニチハ\n12345\n12345\n" biteload a place = 0 pos_x = 0 pos_y = 0 enter = "" wait 100 poke enter,1,0xBD//改行の文字コード? repeat chkbite place if biteinfo(1) = enter{ place += 2 pos_x = 0 pos_y += y_max y_max = 0 await 500 continue } pos pos_x,pos_y mes biteinfo(1) pos_x += ginfo(14) if ginfo(15) > y_max:y_max = ginfo(15) if pos_x >= 400{ pos_x = 0 pos_y += y_max y_max = 0 } if biteinfo(0) = -1 : break place += biteinfo(0) await 40 loop



この記事に返信する


GENKI

リンク

2010/2/14(Sun) 19:40:21|NO.30603

よくわからないけど関連するっぽい資料でも置いておきます。
http://hspdev-wiki.net/?cmd=read&page=String%2F%B2%FE%B9%D4



窓口

リンク

2010/2/14(Sun) 19:46:39|NO.30604

メインループをこのように変更したら動きます。
どうやら、文字列の最後まで進むと、continue命令により、repeatの先頭に戻り続けていたようです。
それと、メインループをbreakするスクリプトの条件式もどうやら間違っていたようです。

随所にある。ユーザー定義命令の意味がいまいち解らなかったので、解読に時間がかかってしまいました。
もう少し、コメントを増やしてもいいのではないでしょうか?

失礼かもですが。
実際スクリプトが読みにくく、無駄が多いような気がします。


repeat if place >= strlen(a) : break chkbite place if biteinfo(1) = enter{ place += 2 pos_x = 0 pos_y += y_max y_max = 0 await 500 continue } pos pos_x,pos_y mes biteinfo(1) pos_x += ginfo(14) if ginfo(15) > y_max:y_max = ginfo(15) if pos_x >= 400{ pos_x = 0 pos_y += y_max y_max = 0 } place += biteinfo(0) logmes str(place) await 40 loop


それともう一つ。
Unicodeを使うことを提案してみます。
Uncodeは、全ての文字コードが2byteに統一されますので、余計な判定はほとんど必要ありません。


; 文字列 string = "\nUnicode\nをHSPで!" ; メッセージサイズ1 の保存 buffer 1 : mes "X" g_mesy = ginfo_mesy cls ; 作業用変数の初期化 gsel 0 index = 0 mesx = 0 : mesy = 0 ; 文字列をUnicodeに変換。 sdim ws,strlen(string)*2+2 : cnvstow ws,string sdim work,2 ; プリント開始 repeat Unchar = wpeek(ws,index) ; 2byte 毎に取得 logmes strf("%04x" , Unchar ) switch Unchar case 0x0000 ; 文字列の終端 Unsize = cnt : break swbreak case 0x000d ; リターンコード(改行文字 の 一文字目)だった場合。 index+=2 ; 次の[0x000a]を飛ばす。 mesx = 0 : mesy += g_mesy ; 改行処理 swbreak case 0x000a swbreak default ; 文字のプリント pos mesx , mesy : mes cnvwtos(Unchar) ; Unicodeを通常文字列へ mesx += ginfo_mesx ; 一文字シフト swbreak swend index+=2 ; 一文字シフト wait 1 loop



shiron

リンク

2010/2/14(Sun) 20:26:48|NO.30605

返信ありがとうございます!お二方まとめてですみません。
GENKIさん
資料どうもありがとうございます。ここでかなり格闘しました。全角のカタカナだと
1byteで返されてしまったりなかなかうまくいかなくて挫折してしまいました。
そこでいろいろ調べていてgetstrで1文字取得してバイト数を調べたらできるのでは!?
というものだったんですが説明不足で申し訳ないです(汗

窓口さん
どちらともうまく実行できました。logmesすると分かりやすくてよかったです。
Unicodeとやらを聞いたことはあったのですが、初めてどのようなものか知りました。
全部2byteに統一してくれるなんて便利すぎる!これで面倒なチェックともおさらばですね!


また機会があればよろしくお願いします。どうもありがとうございました!



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