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


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0505
あんさTXTから文字列の検索7解決


あんさ

リンク

2014/5/5(Mon) 01:58:27|NO.61846

HSPで*.txtファイルをロードし、その中文字列を検索して、その文字列と一致した「行」を返す方法を教えていただきたいです。

たとえば
[example.txt]
00001
00002
00003
00004
00005

このテキストをロードし、inputに「00003」と入力したとして、
example.txtに00003は3行目にあるので、
変数に3を代入してほしいのです。

拙い日本語で申し訳ありません。
よろしくお願いいたします。



この記事に返信する


FunnyMaker

リンク

2014/5/5(Mon) 04:09:43|NO.61847

こんな感じでしょうか。
ヒントをたくさん書きましたので、何をやっているかわかると思います。


*InitDynamicVars sdim buf_input,1000 sdim buf_mesbox,1000 buf_mesbox = {" 00001 00002 00003 00004 00005 "} *MakeAppWindow screen 0,300,200,0 title "FindStringFromText" syscolor 4 : boxf sysfont 17 syscolor 7 pos 5,5 : mes "keyword" pos 50,3 : input buf_input,195,18,0 objsize 45,20 : objmode 1,1 pos 250,2 : button gosub "Search",*Search pos 5,30 : mes "source" pos 5,45 : mesbox buf_mesbox,290,150,4 objsize 60,20 pos 235,23 : button gosub "Open File",*OpenFile goto *Wait_Main *OpenFile dialog "*",16,"" if stat = 0 : end sdim buf_mesbox,1000 notesel buf_mesbox noteload refstr objprm 2,buf_mesbox *Wait_Main stop *Search //////////////////////////////////////////// ここがミソ //////////////////////////////////////////// ; 〜留意すること〜 ; 改行とて所詮は「コード」で表現されるから普通の文字と似たようなもの。 ; 改行コード (13 10) も文字列としてinstrで検索できます。 ; だから複数行文字列もコンピュータから見ればただの直列なデータです。 ; (ex) あいう ; えおか ; きくけ ; ・・・ ; ; ↓ ; ; あいう[改行コード]えおか[改行コード]きくけ・・・ x(0) = instr(buf_mesbox,0,buf_input) ;先頭からキーワードを探す if x(0) = -1 : dialog "The keyword could not be found in the source.",1 : return buf = strmid(buf_mesbox,0,x(0));キーワード直前までの文字列を全部bufにコピー。もちろん改行コードも含まれている。(※peekやpokeを使って文字列が操れるなら、こういうことをせずにもう少し高速化できるがここでは紹介しない。) strrep buf,"\n","\n" ;bufの中の改行コード(13 10)の数を数える。結果はstatに入る。 x(1) = stat+1 ;それに1を足せば、キーワードが"含まれ"ている行の番号。(※あくまで含まれていることがわかるだけで、この時点では一致とは断定できない。) notesel buf_mesbox noteget buf,x(1)-1 ;その行を見てみる。 if buf_input ! buf : dialog "The keyword could not be found in the source.",1 : return ;ただ含まれていただけで完全には一致していないということが判明したら、ここでアウト。 dialog "The keyword was found in line "+x(1)+" for the first time.",0 return

でも、これはキーワードの複数行でのヒットを想定していません。
もし複数行ヒットの考慮が必要なら、これを参考にして機能拡張にトライしてみましょう。



FunnyMaker

リンク

2014/5/5(Mon) 04:18:42|NO.61848

↑のソースに不備がありました。35行目に「return」を追加しておいてください。
そうしないと、たぶん33回目のファイルオープンでサブルーチンのネストエラーになります。



FunnyMaker

リンク

2014/5/5(Mon) 04:27:27|NO.61849

度々すみません。
言い忘れてたことがあったので、追加です。

「notegetで1行ずつ取り出して比較」を繰り返せばいいじゃん?

と思うかもしれませんが、これは避けた方がいいです。
行数が少ないうちはいいのですが、数百行程度になると激遅になります。
noteget自体が遅いのです。(多分バッファオーバーリードとかにならないように裏でいろいろお膳立てをしてくれるから遅くなってしまうのだと思いますが)



noteload

リンク

2014/5/5(Mon) 04:28:01|NO.61850

模範解答その2
	
;FileNameで指定したファイルを、LoadBufferに読み込む notesel LoadBuffer noteload "example.txt" LineLimit=notemax ;LineLimit=読み込んだ総行数 TargetString="" ;文字列型で初期化しておくのがミソ input TargetString *MainLoop ;リターンキーが押されたら*Seatchに飛ぶ ;割り込み命令(onkey)は使わずに、stickで検出してみた stick tmp if tmp=32:gosub *Seatch await goto *MainLoop *Seatch ;inputに入れた文字(TargetString)と最初に一致した行をResultに入れて返す ;みつからなかったときはResult=0 Result=0 repeat LineLimit noteget S,cnt ;バッファから1行読み込んで if S=TargetString{ ;入力した文字列と一致したら Result=cnt+1 ;Resultに行番号を入れて break ;ループを抜ける } loop ;解りやすいようにmesで出してみた mes str(Result) return



fortunehill

リンク

2014/5/5(Mon) 15:09:36|NO.61860

/*ご参考(蛇足的)*/

notesel dd ; noteload "example.txt" dd = {"00001 00002 00003 00004 00005"} combox ii,,dd ss = "00004" input ss onkey gosub *label ;input上でenterを押した時の処理 stop *label objsel -1 :if (stat == 1) {;combox(listbox)の検索機能を利用する(但し完全一致) if (wparam == 13) {sendmsg objinfo(0,2),$14D,0,varptr(ss) ;CB_SELECTSTRING ii = stat :title ""+ii}} return



m

リンク

2014/5/5(Mon) 17:47:39|NO.61862

既に解答がいくつか出ていますが折角なので getstr を使用する方法です。


list = {" 00001 00002 00003 00004 00005 00003 "} keyword = "00003" objsize 200,200 : mesbox list objsize 200,20 : input keyword onkey gosub *SEARCH_KEYWORD stop *SEARCH_KEYWORD await : color 255,255,255 : boxf : pos 220,20 : color mes keyword+"を探す" _temp = "" : i = 0 repeat -1,1 getstr _temp, list, i // 改行区切りで文字列を得る if strsize == 0 : break if _temp == keyword { // 文字列比較 mes ""+cnt+"行目" } i += strsize // 次の検索インデックスに移動 loop return

質問内容とズレますが noteget は確かに行数が多くなると遅くなりますね。

#uselib "winmm.dll" #cfunc timeGetTime "timeGetTime" list = "" : repeat 10000 : list += "\n" : loop : notesel list time = timeGetTime() repeat 10000 : noteget _temp,0 : loop mes "noteget 0行目:"+(timeGetTime()-time)+"ms" time = timeGetTime() repeat 10000 : noteget _temp,9999 : loop mes "noteget 9999行目:"+(timeGetTime()-time)+"ms"



あんさ1

リンク

2014/5/11(Sun) 21:48:17|NO.61963

お返事遅くなってしまい申し訳ありません。

無事に自分の作りたいものができました。
皆さん、ご回答ありがとうございました!



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