split命令を追加してみる
IRC で
23:10 f_the_darudaru perlの my( $a,$b,$c ) = split( /,/ , $data); 見たいな記述の導入を検討師弟t抱けると幸いです(鬼 f_the_darudaru 他人事だからいえることを堂々と、血も涙も無い感じで・・・!! 23:12 fujidig わー>< f_the_darudaru でも、この記述は、初心者niha大変な武器になると思うのですよ 23:13 fujidig 多重代入はRubyにもあるから知ってますんですけど、配列オブジェクト(値)がないと駄目じゃないですかねえ As ひとつのモジュールに、現在作成されているモジュール型変数の数を取得する関数を導入してほしいですw 23:14 f_the_darudaru フウム elfizm C++でいう静的メンバで解決できそう? 23:15 fujidig modinitでcount++してmodtermでcount--とか。 f_the_darudaru むしろ、splitの命令で、split( "分割する記号" , 受け取る変数1,受け取る変数2,受け取る変数3,....)mitaina f_the_darudaru 見たいな書き方ならできるかも? As >>modinitでcount++してmodtermでcount--とか。 23:16 As その手があったか!!orz fujidig うん、それなら出来そうだねえ。<split( "分割する記号" , 受け取る変数1,受け取る変数2,受け取る変数3,....) f_the_darudaru おっと、元データが抜けた(笑 elfizm www 23:17 fujidig strfでHSP初の可変長の関数を作ったばっかりだしw f_the_darudaru 可変長引数関数が出来たのなら、難しくは無い話ですな。 23:18 f_the_darudaru 時折、掲示板でも「noteloadで読み込んだデータを分割したい」とかあるので、良いかもしれません。 23:20 fujidig 配列変数で受け取る方が汎用性がある気がするんだけれど、、「一つ一つ別の変数で受け取る命令はあるのになんで配列で受け取る命令はないんだよ」ってなりそうな気も 23:21 f_the_darudaru フム f_the_darudaru では二通り(鬼 23:22 fujidig うぎゃー
ということがあったので作ってみました。
diff -Naru openhsp.orig/hsp3/hsp3int.cpp openhsp/hsp3/hsp3int.cpp --- openhsp.orig/hsp3/hsp3int.cpp Fri Apr 04 22:21:34 2008 +++ openhsp/hsp3/hsp3int.cpp Tue Apr 15 09:36:18 2008 @@ -511,6 +511,59 @@ note.ResumeLineDirect(); break; } + case 0x2a: // split + { + PVal *pval; + int aptr; + char *sptr; + char *sep; + char *newsptr; + int size; + int sep_len; + int n; + int is_last = 0; + + sptr = code_getvptr( &pval, &size ); + if ( pval->flag != HSPVAR_FLAG_STR ) throw HSPERR_TYPE_MISMATCH; + sep = code_gets(); + sep_len = strlen( sep ); + + pval = NULL; + n = 0; + while (1) { + n ++; + newsptr = strstr2( sptr, sep ); + if ( !is_last && *exinfo->npexflg & EXFLG_1 ) { + // 分割結果の数が格納する変数より多ければ最後の変数に配列で格納していく + // ただし最後の要素が a.2 のように要素指定があればそれ以降は全く格納しない + if ( aptr != 0 ) pval = NULL; + is_last = 1; + aptr = 0; + } + if ( is_last ) { + aptr ++; + if ( pval != NULL && aptr >= pval->len[1] ) { + if ( pval->len[2] != 0 ) throw HSPVAR_ERROR_ARRAYOVER; + HspVarCoreReDim( pval, 1, aptr+1 ); + } + } else { + aptr = code_getva( &pval ); + } + if ( pval != NULL ) { + code_setva( pval, aptr, HSPVAR_FLAG_STR, sptr ); + } + if ( newsptr == NULL ) { + // 格納する変数の数が分割できた数より多ければ残った変数それぞれに空文字列を格納する + while( ( *exinfo->npexflg & EXFLG_1 ) == 0 ) { + aptr = code_getva( &pval ); + code_setva( pval, aptr, HSPVAR_FLAG_STR, "" ); + } + break; + } + if ( pval != NULL ) { + pval->offset = aptr; + ((char *)HspVarCorePtr(pval))[newsptr - sptr] = '\0'; + } + sptr = newsptr + sep_len; + } + ctx->stat = n; + break; + } case 0x27: // randomize #ifdef HSPWIN diff -Naru openhsp.orig/hspcmp/hspcmd.cpp openhsp/hspcmp/hspcmd.cpp --- openhsp.orig/hspcmp/hspcmd.cpp Sat Mar 29 22:12:56 2008 +++ openhsp/hspcmp/hspcmd.cpp Tue Apr 15 09:33:06 2008 @@ -97,6 +97,7 @@ "$027 8 randomize", // (changed on ver3.0) "$028 8 noteunsel", // (changed on ver3.0) "$029 8 noteget", // (changed on ver2.55) + "$02a 8 split", // (3.2) // enhanced command (ver2.2)
OpenHSP Copyright (C) 1997-2008, Onion Software/onitama, all rights reserved. This software is provided by the copyright holders and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed.
使い方
第一引数に元データ変数、第二引数にセパレータ文字列、第三引数以降に結果が入る変数を指定します。 stat にいくつ分割できたかが返ります。
buf = "tarou:18:male" split buf, ":", name, age, sex mes name mes age mes sex mes stat
第三引数を指定せずにいくつ分割できたかだけをもらう
buf = "よそはよそ、うちはうち。そよそよ。ご飯をよそいなさい。" split buf, "よそ" mes buf mes "上の文章に「よそ」は何個あるかな?" mes "答えは"+(stat - 1)+"個"
文字列中に指定した文字列がいくつあるか数えることができます。
分割できた数の方が結果の変数の数より大きければ一番後ろに指定した変数に配列として入っていきます。
buf = "tarou:18:male" split buf, ":", results repeat stat mes results.cnt loop