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


HSPTV!掲示板


未解決 解決 停止 削除要請

2009
0328
ssパラメーターの取得がうまくいかない12解決


ss

リンク

2009/3/28(Sat) 10:34:50|NO.24217

今,ファイルを読み込んで、
それを元に動作を行うHSP自体のようなものを作っているのですが
pos 10,20
のようなすうじだけのパラメーターの取得は、


#deffunc GetParameter var p1, int p2, array p3, int p4 prmcnt=p2 repeat if cnt>p4+1 : return -1 //パラメーターの数が多すぎる場合はエラー getstr p3(cnt),p1,prmcnt,',',1024 prmcnt+strlen(p3(cnt))+1 if p3(cnt) = "" : break loop return 0
のスクリプトでできるのですが、
mes "test"
のようなダブルクオーテーションで囲まれたところは、
中だけ取り出すようにしたいのですがうまくいきません。
特に、
dialog "message",0,"test"
のような文字列と数字が混ざっているとなおさらです。



この記事に返信する


ss

リンク

2009/3/28(Sat) 10:39:16|NO.24218

GetParameterの引数の説明を忘れていました。
p1 パラメーターを取得したい命令が入った変数
p2 オフセット(ここで指定した文字数以降からパラメーターの取得を開始します)
p3 パラメーターが取得される配列変数
パラメーター1はp3(0)、パラメーター2はp3(1)・・・というように格納されていきます
p4 正しいパラメーターの数



春他人

リンク

2009/3/28(Sat) 11:06:00|NO.24220

答えを教えるのは簡単ですがここはヒントだけで。

パラメーターを取得した後にそのパラメーターの1文字目をチェックする。
一文字目が["]だったら""の内部だけを抜き出す。

こんな感じででできると思います。
必要な命令等は自分で調べることが重要です。



ss

リンク

2009/3/28(Sat) 11:07:36|NO.24222

もう行ったのですが、
エラー判定がうまくいかないのです


#deffunc GetParameter var p1, int p2, array p3, int p4 prmcnt=p2 repeat if cnt>p4 : return -1 if strmid(p1,prmcnt,1) = "\"" { getstr p3(cnt),p1,prmcnt+1,'"',1024 prmcnt+strlen(p3(cnt))+3 if cnt=p4-1 : if peek(p1,prmcnt-2) = '"' : prmcnt-1 } else { getstr p3(cnt),p1,prmcnt,',',1024 prmcnt+strlen(p3(cnt))+1 if p3(cnt) = "" : break } loop return 0



春他人

リンク

2009/3/28(Sat) 11:41:41|NO.24224

cntは基本的に0から始まります。
すなわちこのスクリプトの場合、
cntは常に取得したいパラメーターの番号-1の値を示します。
このエラー処理ですとcnt>パラメーターの数となっているので
cntの値が最低p4+1になります。
しかしこの条件を満たす前に
if p3(cnt) = "" : break

でループを抜けてしまいます。 どうすればいいかはたぶんこれでわかると思います。



ss

リンク

2009/3/28(Sat) 12:04:09|NO.24226

うーん・・・ちょっとわからないです。
まだエラー判定がうまくいきません
引数の数を取得したい数より多くしても、statに-1が返りません。

#deffunc GetParameter var p1, int p2, array p3, int p4 prmcnt=p2 repeat if cnt>p4+1 : return -1 if cnt!0 : if p3(cnt-1) = "" : break if strmid(p1,prmcnt,1) = "\"" { getstr p3(cnt),p1,prmcnt+1,'"',1024 prmcnt+strlen(p3(cnt))+3 if cnt=p4-1 : if peek(p1,prmcnt-2) = '"' : prmcnt-1 } else { getstr p3(cnt),p1,prmcnt,',',1024 prmcnt+strlen(p3(cnt))+1 } loop return 0



春他人

リンク

2009/3/28(Sat) 13:04:45|NO.24228

if cnt=p4-1 : if peek(p1,prmcnt-2) = '"' : prmcnt-1

がたぶん原因ですね。 p4番目の要素が文字列だとここでprmcntが[,]の前になってしまうので 次のループでp3(cnt-1)が空になります。 よってエラーになりません。 この行は意味をなしてないようなので消しても問題ないと思います。



ss

リンク

2009/3/28(Sat) 13:15:45|NO.24229

しかし、その行を消して、

#module #deffunc GetParameter var p1, int p2, array p3, int p4 prmcnt=p2 repeat if cnt>p4+1 : return -1 if cnt!0 : if p3(cnt-1) = "" : break if strmid(p1,prmcnt,1) = "\"" { getstr p3(cnt),p1,prmcnt+1,'"',1024 prmcnt+strlen(p3(cnt))+3 ;if cnt=p4-1 : if peek(p1,prmcnt-2) = '"' : prmcnt-1 } else { getstr p3(cnt),p1,prmcnt,',',1024 prmcnt+strlen(p3(cnt))+1 } loop return 0 #global a="mes \"ああああああああああああああああああああああああああああああああああああああああああああああああああ\"" sdim get,1024 GetParameter a,0,get,1
を実行するとばっふぁオーバーフローが発生してしまいます。
prmcntの値がp1の文字列の長さを超えてしまうからです。



春他人

リンク

2009/3/29(Sun) 14:33:44|NO.24241

いろいろとやってみましたが
あのままで直すのは私には不可能だったので私なりに作り直してみました。
#module
#deffunc GetParameter var p1, int p2, array p3, int p4 prmcnt=p2 repeat p4 getstr p3(cnt),p1,prmcnt,',',1024 if peek(p3(cnt),0)='"':p3(cnt)=strmid(p3(cnt),1,strlen(p3(cnt))-2) prmcnt+=strsize loop if strlen(p1)>prmcnt:return -1 return 0 #global a="mes \"qwertyuiopasdfghjklzxvbnureyjdgnhfjyfhhhhmnhfmjmqwertyuioasdfghjzxdfcgvhjbszxdfcgvhjbzsxfcgvbhzdxfgvhbjnzxdtcfgvh\",6,\"jyr\"" sdim get,1024 GetParameter a,0,get,3 foreach get mes get(cnt) loop
こんな感じでいけると思いますが
パラメーターの省略でパラメーター数が多くなったときの
エラー処理に対応させることはできませんでした。
私にはこれが精一杯です。
中途半端になってしまい申し訳ありませんでした。



KIMU

リンク

2009/3/29(Sun) 15:56:32|NO.24243

取り出したパラメーターはp3(0)に命令+パラメータなのかパラメーターだけなのか、どうなるのが正解のか良く分からないですが・・・
NO.24217のは命令+パラメータが抜き出されるけど
NO.24218の説明では「パラメーター1はp3(0)」と、パラメーターだけに読める
NO.24229のif strmid(p1,prmcnt,1) = "\"" が一致する事はp2が0の場合有り得ない
p1の前提条件(一行一命令とか)も良く分からないので、自分的解釈でやってみた↓


#module #deffunc GetParameter var p1, int p2, array p3, int p4 prmcnt=p2 sl=strlen(p1) repeat p4 if prmcnt>=sl {if cnt!0 {return cnt} else {return -2}} //パラメーター指定数よりデータ数が少ない時(収得した数) 最初からデータが無い(-2) if strmid(p1,prmcnt,1) = "\"" { getstr p3(cnt),p1,prmcnt+1,'"',1024 prmcnt+strsize+2 } else { getstr p3(cnt),p1,prmcnt,',',1024 prmcnt+strsize } mes "p"+(cnt+1)+"="+p3(cnt) //収得パラメーター表示 loop if prmcnt>sl :return 0 //パラメーター指定数とデータ数が一致(0) return -1 ;データ数が多い時(-1) #global a="dialog \"message\",0,\"test\"" sdim get,1024 getstr b,a,0,' ',1024 mes "命令名="+b GetParameter a,strsize,get,3 mes "stat="+stat



窓口

リンク

2009/3/30(Mon) 21:53:01|NO.24266

取りあえず「"」が入ったままのパラメータ取得で大丈夫だと思います。

配列変数には、数列か文字列どちらかしか入りませんから、変数型は文字列型に統一して、

ダブルクオーテーションが有るパラメータは、文字列、無いパラメータは整数として区別して。
後で、命令の処理をするときに、「"」の無いパラメータだけint()で変換したほうがいいと思います。

そうでないと、混乱するのではないでしょうか?



KIMU

リンク

2009/3/30(Mon) 23:23:57|NO.24268

NO.24243のはrepeat中にreturnしちゃってたので直しました。


#module #deffunc GetParameter var p1, int p2, array p3, int p4, local c prmcnt=p2 sl=strlen(p1) repeat p4 if prmcnt>=sl {if cnt!0 {c=cnt:break} else {c=-2:break}} //パラメータ指定数よりデータ数が少ない時(収得した数) 最初からデータが無い(-2) if strmid(p1,prmcnt,1) = "\"" { getstr p3(cnt),p1,prmcnt+1,'"',1024 prmcnt+strsize+2 } else { getstr p3(cnt),p1,prmcnt,',',1024 prmcnt+strsize } mes "p"+(cnt+1)+"="+p3(cnt) //収得パラメータ表示 loop if prmcnt<sl :return -1 ;データ数が多い時(-1) return c #global m={"boxf 200,100,300,200 mes \"GetParameterテスト\""} sdim get,1024 repeat getstr a,m,idx,0,1024 if strsize=0 {break} idx+strsize getstr b,a,0,' ',1024 mes "命令名="+b switch b case "boxf" GetParameter a,strsize,get,4 mes "stat="+stat boxf int(get(0)),int(get(1)),int(get(2)),int(get(3)) swbreak case "mes" GetParameter a,strsize,get,1 mes "stat="+stat mes get swbreak swend loop



ss

リンク

2009/4/2(Thu) 14:53:09|NO.24338

ありがとうございます。
うまくいきました。



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