|
|
2009/4/25(Sat) 18:47:21|NO.24805
HSPで文字列の最初にあるスペースやタブを削除する命令を作ったのですが、
実行すると文字の最後のほうに変な文字が混ざってしまいます。
どうすれば変な文字が混ざらないようにできますか?
#module
#deffunc DeleteSpace var p1
dels = ""
notesel p1
repeat notemax
noteget dels, cnt
repeat strlen(dels)
if strmid(dels, 0, 1) == " " | strmid(dels, 0, 1) == " " {
dels = strmid(dels, 1, strlen(dels))
} else {
break
}
loop
noteadd dels, cnt, 1
loop
return
#global
|
|
2009/4/25(Sat) 19:04:02|NO.24807
この命令(DeleteSpace)の使い方はどうすればいいのですか?
どんな風に使えば、変な文字が混ざる現象が再現できますか?指定する文字列はどんなものですか?
スクリプトを貼るときは、コピペするだけで問題が再現できるもののほうが適切な回答を得やすくなりますよ。
たぶんあと2~3行程度スクリプトを付け足せばいいだけだと思うので、大した労力でもないでしょう。(逆にそれがないのは読む側にとっては凄く大変です。)
|
|
2009/4/25(Sat) 19:06:39|NO.24808
|
|
2009/4/25(Sat) 19:17:12|NO.24809
すみませんDeleteSpaceの使い方を乗せるのを忘れていました。
さっきのモジュールに以下のスクリプトを追加してください。
//DeleteSpace
//p1 : スペースを削除する文字列が入った変数
dialog "txt", 16
fname = refstr
exist fname
sdim buf, strsize
bload fname, buf
DeleteSpace buf
dialog "txt", 17
bsave refstr, buf
end
|
|
2009/4/25(Sat) 20:24:16|NO.24811
これを使えばちゃんと削除できます
/*
DelSpeace prm1
prm1・・・スペースを削除したい文字列
結果はシステム変数refstrに返ります
*/
#module
#deffunc DelSpeace str prm1
sdim source , strlen(prm1)+1
sdim ope , strlen(prm1)+1
count=0
posi=0
source=prm1
repeat strlen(source)
repeat
if(wpeek(source,count)==16513):count+=2:else:break
loop
if (peek(source,count)!=32){
poke ope,posi,peek(source,count)
posi++
}
count++
loop
return ope
#global
//以下、サンプル
sdim test
test="A B C D E F G"
print "元の文字列:"+test
DelSpeace test
print "スペースを削除したもの:"+refstr
各命令の解説はのせてないから自分で調べてください
|
|
2009/4/25(Sat) 20:48:35|NO.24812
あの・・・すみません文字列の最初にあるスペースを削除したいのですが・・・
たとえば
スペーススペースAスペースBをDeleteSpaceにかけると
AスペースB
みたいになる命令が作りたかったのです。
Hiroakiさんが教えてくれたプログラムを改造すればできそうなのですが、
他人の書いたソースを解読するのは難しいので・・・
|
|
2009/4/25(Sat) 21:22:28|NO.24813
>あの・・・すみません文字列の最初にあるスペースを削除したいのですが・・・
失礼しました
以下のもので文字列の最初にあるスペースを削除できます
/*
DelSpeace prm1
prm1・・・スペースを削除したい文字列
結果はシステム変数refstrに返ります
*/
#module
#deffunc DelSpeace str prm1
sdim source , strlen(prm1)+1
sdim ope , strlen(prm1)+1
count=0
source=prm1
repeat
if (peek(source,count)==32){
count++
}else{
if(wpeek(source,count)==16513):count+=2:else:break
}
loop
print count1
ope=strmid(source,count,strlen(source)-(count))
return ope
#global
//以下、サンプル
sdim test
test=" A B C D E F G "
print "元の文字列:"+test
DelSpeace test
print "スペースを削除したもの(わかりやすくするため[]で文字列を囲んでいます\n["+refstr+"]"
|
|
2009/4/25(Sat) 21:42:58|NO.24814
ちなみに文字列の前後のスペースを削除するには
これでできます(おまけ情報)
つまり スペースAスペースBスペースをDelSpeaceにかけると
AスペースBにするやつ
/*
DelSpeace prm1
prm1・・・スペースを削除したい文字列
結果はシステム変数refstrに返ります
*/
#module
#deffunc DelSpeace str prm1
sdim source , strlen(prm1)+1
sdim ope , strlen(prm1)+1
count=0
count1=0
source=prm1
repeat
if (peek(source,count)==32){
count++
}else{
if(wpeek(source,count)==16513):count+=2:else:break
}
loop
repeat
if (peek(source,strlen(source)-count1-1)==32){
count1++
}else{
if(wpeek(source,strlen(source)-count1-2)==16513):count1+=2:else:break
}
loop
print count1
ope=strmid(source,count,strlen(source)-(count+count1))
return ope
#global
//以下、サンプル
sdim test
test=" A B C D E F G "
print "元の文字列:"+test
DelSpeace test
print "スペースを削除したもの(わかりやすくするため[]で文字列を囲んでいます\n["+refstr+"]"
|
|
2009/4/25(Sat) 21:43:16|NO.24815
問題の原因は切り出ししている文字の長さではないですか?
strmid の結果得られる文字列の長さは、もとの文字列の長さとは違うはずですよね。
|
|
2009/4/25(Sat) 21:44:01|NO.24816
#module
#defcfunc DeleteSpace var p1
sdim p2,strlen(p1)
if (instr(p1,0," ")=-1)&(instr(p1,0,"\t")=-1) : return p1
repeat strlen(p1)
if (peek(p1,cnt)!' ')&(peek(p1,cnt)!'\t'){
memcpy p2,p1,strlen(p1)-cnt+1,0,cnt : break}
loop
return p2
#global
string=" test"
mes string+"→"+DeleteSpace(string)
string=" test"
mes string+"→"+DeleteSpace(string)
string=" test"
mes string+"→"+DeleteSpace(string)
string=" test"
mes string+"→"+DeleteSpace(string)
生意気にmemcpyなんて使ってみた。
投稿者さんのソースはちゃんと見ていないのでよく分かりませんが、
文字の最後の方にーっていうのはヌル文字が入ってないとかそんなオチな気がします。
|
|
2009/4/25(Sat) 21:45:53|NO.24817
>SYAMさん
文字列の長さを求めるのはstrmidではなくstrlenです
|
|
2009/4/25(Sat) 22:34:37|NO.24819
「strmid の結果得られる文字列」 の 長さ
です。
|
|
2009/4/25(Sat) 23:33:30|NO.24823
久しぶりに紘章が出てきたとおもったらこれか。日本語読めないなら黙ってみてろ。
|
|
2009/4/26(Sun) 01:04:40|NO.24828
> 文字の最後の方にーっていうのはヌル文字が入ってないとかそんなオチな気がします。
bsaveはヌル文字(終了コード)を無視するので、たぶんそれが正解だと思います。
notesave命令で保存するようにすれば解決すると思います。
どうしてもbsave命令を使いたいなら
bsave refstr, buf, strlen(buf)
としてください。理由は…マニュアルの
「HSP3文字列のひみつ(中級者向け) (hsp3str.htm) 」
を先ずは読んでみてください。
それでも分からなければまた質問ください。
>>NO.24809
これではテキストファイルの内容によっては再現できませんね。再現できても気づかないかも?
どのテキストファイルを使うかも教えてくれると助かったんですが…。
とりあえず私はHSP3のreadme.txt使ってみたら再現できました。
> たぶんあと2~3行程度スクリプトを付け足せばいいだけだと思うので
2バイト文字の文字化け問題化と思ったんですが、読みが大ハズレでしたね。失敗。
|
|
2009/4/26(Sun) 01:15:36|NO.24830
ごめんなさい strmidは対象の文字列が短かったら終端までしか返さないようになってますね。
私の回答、まったく見当違いでしたorz
|
|
2009/4/26(Sun) 09:56:36|NO.24834
>「strmid の結果得られる文字列」 の 長さ
あ、そでした・・・・すみませんでした・・・・・・
さて、NO.24811、NO.24813、NO.24814
に書いたやつなのだが、ちょっと論理的なバグありました
それらを訂正したやつにTABを削除する機能を追加し、1つのファイル
にたものをHPスペースにUPしました
以下のURLからDLしご自由にお使いください
URL: http://hiroaki2008.ktkr.net/hsp/sample/DelSpeMod.hsp
|
|
2009/4/26(Sun) 12:02:54|NO.24837
|
|
2009/4/26(Sun) 16:46:23|NO.24838
問題点を指摘するのではなく、自分の考えを押し付けるようなレスは無視するとして、
>>if strmid(dels, 0, 1) == " " | strmid(dels, 0, 1) == " "
タブを文字として指定するのは "\t" だったかな?
間違っていたら、ごめんなさい。
|
|
2009/4/26(Sun) 21:17:05|NO.24847
ちゃんと読まずに書き込みしてごめんなさい
dels = strmid(dels, 1, strlen(dels))
たぶん変なのここですよ
文字列の長さは、削るスペース分一文字減らせば、いいと思いますよ
削った後の長さでstrmidで切り出せばいいと思います
レスが多くて問題点把握できてないですけど
|
|
2009/4/26(Sun) 21:28:30|NO.24849
> 問題の原因は切り出ししている文字の長さではないですか?
> strmid の結果得られる文字列の長さは、もとの文字列の長さとは違うはずですよね。
説明不足ですみません
もう指摘されてましたね
dels = strmid(dels, 1, strlen(dels))
これに例えば" abc"を渡すと、
delsの" abc"の長さ4で渡します。
そうなると1つまり2番目のインデックスから4文字切り出します。
代入したいのは"abc"の3文字です。
3文字代入したいのに切り出す文字数が4文字なので、
メモリ上の"abc"のなんだかわかない次の値を代入してしまいます。
スペースを削除したい文字列が" abc"なら切り出す文字は3文字のはず。
なのに4文字代入する操作なので変な値まで代入してしまうのでしょう。
#ここの改行ルールがいまいちわかりません。みぐるしくてスミマセン
|
|
2009/4/26(Sun) 21:47:45|NO.24851
さて、NO.24805のスクリプトだが
>if strmid(dels, 0, 1) == " " | strmid(dels, 0, 1) == " " {
> dels = strmid(dels, 1, strlen(dels))
> } else {
> break
> }
この部分にミスがあります
まずif文の |の右側のstrmid(dels, 0, 1) == " "の部分が違う、
全角スペースは2文字分バッファを有します。
したがってstrmid(dels, 0, 2) == " "が正しくなります。
ただしこの場合、dels = strmid(dels, 1, strlen(dels))の第2パラメータも2
にしなくてはなりません。よって
if strmid(dels, 0, 1) == " "{
dels = strmid(dels, 1, strlen(dels))
}else:if strmid(dels, 0, 2) == " "{
dels = strmid(dels, 2, strlen(dels))
}else{
break
}
が正しいスクリプトになります。
|
|
2009/4/26(Sun) 22:42:09|NO.24856
>> y.tackさん
せっかくなのでSYAMさんのNO.24830も読んでみてください。
それとstrmidのヘルプも読み直してみることをお勧めします。
> #ここの改行ルールがいまいちわかりません。みぐるしくてスミマセン
<pre>…スクリプト…</pre>
という感じで1行に<pre>~</pre>を書いた後の文章は改行が無視されてしまうようです。
<pre>
…スクリプト…
</pre>
と言う感じで書くと改行は無視されなくなります。
>> KAさん
> タブを文字として指定するのは "\t" だったかな?
> 間違っていたら、ごめんなさい。
それであってます。
|
|