|
|
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"
のような文字列と数字が混ざっているとなおさらです。
|
|
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文字目をチェックする。
一文字目が["]だったら""の内部だけを抜き出す。
こんな感じででできると思います。
必要な命令等は自分で調べることが重要です。
|
|
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
でループを抜けてしまいます。
どうすればいいかはたぶんこれでわかると思います。
|
|
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)が空になります。
よってエラーになりません。
この行は意味をなしてないようなので消しても問題ないと思います。
|
|
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
こんな感じでいけると思いますが
パラメーターの省略でパラメーター数が多くなったときの
エラー処理に対応させることはできませんでした。
私にはこれが精一杯です。
中途半端になってしまい申し訳ありませんでした。
|
|
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()で変換したほうがいいと思います。
そうでないと、混乱するのではないでしょうか?
|
|
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
|
|
2009/4/2(Thu) 14:53:09|NO.24338
ありがとうございます。
うまくいきました。
|
|