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


HSPTV!掲示板


未解決 解決 停止 削除要請

2006
0901
風の谷のウマシカ#defcfuncの書き方について5解決


風の谷のウマシカ

リンク

2006/9/1(Fri) 02:50:42|NO.2208

マニュアルを見ていると、defcfuncについては、ものすごくアッサリした説明しかなくて、
よくわかりません。

とにかく自分で作ってみました。下記はテキストを検索して、改行やスペースが見つかったら、
問答無用で全部削除する関数(のつもり)です。ユーザー定義関数にせず、普通のスクリプト内で使えば、
普通に動くので、実用面では問題ないのですが、#defcfuncの練習用です。
下のやり方だと、なぜか途中でエラーが出ます。



#module #defcfunc DelMissLetters str letters sdim letters ;\nを検索して削除 repeat Index=instr(letters,0,"\n")/////////////////////////エラーメッセージ「変数名が指定されていません」が出る if Index=-1 : break letters=strmid(letters,0,Index)+strmid(letters,Index+2,200) loop ;半角スペース" "を検索して削除 repeat Index=instr(letters,0," ") if Index=-1 : break letters=strmid(letters,0,Index)+strmid(letters,Index+2,200) loop ;全角スペース" "を検索して削除 repeat Index=instr(letters,0," ") if Index=-1 : break letters=strmid(letters,0,Index)+strmid(letters,Index+2,200) loop ;戻り値 sdim a return a=letters #global sdim InputtedTXT sdim OutputtingTXT InputtedTXT="aaa bbb \n\n\n ああああ  いいい " OutputtingTXT=DelMissLetters(InputtedTXT) mes OutputtingTXT



あと、検索すると同じ様な事ができるモジュールは色々ある様ですが、
今一つ、構文の流れが理解できません。基本がわからないのに、
サンプルだけお借りしても意味が無いので、それは使わない事にして、
上記のやり方のどこに誤りがあるか見て戴けないでしょうか?

or

#defcfuncの基本だけ、解説している資料があれば、それでも良いのですが・・。
(他の言語の経験が一切無くても、この辺りの事が、わかる様な資料をご存知の方はおられませんか?)



この記事に返信する


osakana

リンク

2006/9/1(Fri) 03:43:53|NO.2210

>#defcfunc DelMissLetters str letters
> sdim letters
まず仮引数と変数に同じ名前を付けてるのが問題です。(うっかりミス?)

>//エラーメッセージ「変数名が指定されていません」が出る
変数型以外の仮引数を instr、strmid などで直接使うと、
このエラーが出るみたいです。
いったん変数に入れて使うか、str の代わりにvar を指定するかで動くと思います。
varにすると呼び出し元のInputtedTXTに結果が反映されます。

わたしもHSP2からHSP3に移行した時は、
#deffuncの仕様が変わり同じエラーに苦しんだことがあります。

少しいじって見ました、
ちゃんと動いてるみたいですよ。

#module #defcfunc DelMissLetters str letters letters2=letters ;\nを検索して削除 repeat Index=instr(letters2,0,"\n") if Index=-1 : break letters2=strmid(letters2,0,Index)+strmid(letters2,Index+2,200) loop ;半角スペース" "を検索して削除 repeat Index=instr(letters2,0," ") if Index=-1 : break letters2=strmid(letters2,0,Index)+strmid(letters2,Index+2,200) loop ;全角スペース" "を検索して削除 repeat Index=instr(letters2,0," ") if Index=-1 : break letters2=strmid(letters2,0,Index)+strmid(letters2,Index+2,200) loop ;戻り値 return letters2 #global sdim InputtedTXT sdim OutputtingTXT InputtedTXT="aaa bbb \n\n\n ああああ  いいい " mes "前:"+InputtedTXT OutputtingTXT=DelMissLetters(InputtedTXT) mes "後:"+OutputtingTXT



Irisawa

リンク

2006/9/1(Fri) 03:51:49|NO.2211


#defcfunc DelMissLetters str letters

ここで、引数にstrを指定しているのに


Index=instr(letters,0,"\n")/////////////////////////エラーメッセージ「変数名が指定されていません」が出る

ここで、そのままinstr関数の引数に渡しているからです。
#deffuncや#defcfuncのint/double/strは定数値です。
instr関数の第1引数は変数を指定する必要があります。
定数は渡せません。
変数はvar(指定された添字のみ), array(配列ごと)で渡します。
呼び出し側は変数を渡さなければいけません。
(定数を引数に指定できません)
もし、どうしても引数に定数を渡したい場合は関数内で一時変数に代入してから使用して
ください。

#defcfuncは単純に#deffuncを関数化したものです。
使い方は#deffuncの説明を読めば大体分かると思います。
(必ず返値を指定する必要があるという点以外は定義の方はまったく違いはありません)
#deffuncでは必ずしも返値は不要で、返値を指定した場合はstatやrefstrなどの
システム変数経由で返されます。
#defcfuncは使用する側では戻り値を受け取る先が必須で関数として記述をしなければ
いけません。



風の谷のウマシカ

リンク

2006/9/1(Fri) 04:16:18|NO.2212

ありがとうございます。ちょっと今、教えて頂いた事を何度も読み返していますが、
最初のスクリプトに誤植発見。

半角スペースを削除するのは
letters=strmid(letters2,0,Index)+strmid(letters2,Index+2,200)
ではなくて
letters=strmid(letters2,0,Index)+strmid(letters2,Index+1,200)
ですね。

まあ、これくらいでは結果がおかしくなるだけで、処理が止まったりはしませんが・・

解決は未だです。ただいま勉強中です。



風の谷のウマシカ

リンク

2006/9/1(Fri) 06:39:46|NO.2214

理解できたと思います。有難うございました。

まず私の場合、「定数」と言う概念を喪失していた様です。もちろん普段、
定数を使っているのですが「定数とは"a+2"の2の様に、決まった値」と、
頭に刻み直すと「変数」の扱いも丁寧になりますね。
そういえば以前、strmid("あいうえお"0,2) なんて実験して、
なぜ上手く行かないか深く考えないで済ませた記憶が・・。
この場合でも同じエラーメッセージが出ますね。
「定数」の概念が曖昧だったからstrmidの解説にある「p1には変数を指定」と
いう辺りを、ちゃんと理解しないで使っていたかも・・。


(解決策1)
osakanaさんが「仮引数」と呼んでおられるのは、最初に
#defcfunc DelMissLetters str letters
とやった場合の「実態の文字列としての"letters"」ですね。この場合は、
letters2=letters
という記述を加えて、変数「letters2」に代入してからでないと「strmid」には
渡せないという事ですね。


(解決策2)
#defcfunc DelMissLetters var letters
とした場合、
letters2=letters
は無しで、エイリアス名に出て来る「変数名としてのletters」を、
そのままstrmidに渡せますね。


どっちのやり方でも、結果的に動くけれどソリューションと論理的に
矛盾が無いのは(解決策2)という事になるでしょうか。
スクリプトの中で「実態としての文字列」を直接記述するなら、
最初から加工が要らないように書いておけば、済む事が大半でしょうから。
(サンプルスクリプトでなければ"aaa bbb \n\n\n・・"なんて書かない)
通常はmesboxか何かを使って、外から取って来た文字列だから、
加工が必要になるのであって、この場合は変数に代入されたカタチで
受け取っているはずですから、スクリプトに「str *」は登場しませんね。

モジュールとして最も素直なカタチは


#module #defcfunc DelMissLetters var letters ;\nを検索して削除 repeat Index=instr(letters,0,"\n") if Index=-1 : break letters=strmid(letters,0,Index)+strmid(letters,Index+2,200) loop ;半角スペース" "を検索して削除 repeat Index=instr(letters,0," ") if Index=-1 : break letters=strmid(letters,0,Index)+strmid(letters,Index+1,200) loop ;全角スペース" "を検索して削除 repeat Index=instr(letters,0," ") if Index=-1 : break letters=strmid(letters,0,Index)+strmid(letters,Index+2,200) loop ;戻り値 return letters #global sdim InputtedTXT sdim OutputtingTXT InputtedTXT="aaa bbb \n\n\n ああああ  いいい " mes "加工前:\n"+InputtedTXT mes "\n------------------------------------------\n" OutputtingTXT=DelMissLetters(InputtedTXT) mes "加工後:\n"+OutputtingTXT

でしょうか? 他のモジュールを読んでも、処理が複雑に見えて理解できなかったのは、
頭の中で、この辺りの問題の切り分けが出来ていなかったのだと思います。



osakana

リンク

2006/9/1(Fri) 18:38:18|NO.2223

>#defcfunc DelMissLetters var letters
> ・
> ・
> ・
>return letters
OutputtingTXT、InputtedTXTが最終的に同じになるので
無理に#defcfuncを使わずに#deffuncを使った方が良いかも知れませんね。
#defcfuncを使うなら戻り値に処理結果を返してはどうでしょう。

buf=MissLetters(InputtedTXT) if buf=0 :stop //エラーならストップ mes "加工後:\n"+InputtedTXT
もしくわ

//InputtedTXTの処理結果をOutputtingTXTに入れるスタイルで buf=DelMissLetters(OutputtingTXT,InputtedTXT) if buf=0 :stop //エラーならストップ mes "加工後:\n"+OutputtingTXT
適当に書いたので軽く流していいですよ。(~~



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