strstr 関数で教えてくださいNo.01787
kyau さん 01/02/18 22:01
 
はじめて投稿いたします。kyau と申します。


タブ区切りの用語集から用語を取得して
一括置換、という処理をするためのマクロを作成し、
一度秀丸マクロライブラリに掲載したことがあるのですが(MetaFileReplace という名
前で)、
ユーザの方から、「文字化け」が発生する、という声が寄せられました。

よくよく調べたら文字化けの原因はどうやらタブを使用した文字位置の取得にありそう
だな、
ということまではわかりました。具体的な状況を説明するのが難しいのですが、、、。

---------------------------------------------------------
//タブ区切りの用語集から文字列(タブの前の文字列とタブの後の文字列)を取得する

config "t2";

golinetop2;
#x0 = x; #y0 = y;
golineend2;

#x1 = x;

$tarline = gettext(#x0, #y0, x, y);

#key1 = strstr($tarline, "\^");
#key2 = strstr($tarline, "\t");//タブの位置を取得

$jap = gettext(#key1, #y0, #key2, #y0);//$jap は正しく取得される
$eng = gettext(#key2 + 1, #y0, #x1, #y0); //$eng に化けた文字列が格納されるこ
とがある。ここの #key + 1 という式が原因??
---------------------------------------------------------

原因がわからないので、現在はタブを、一般にはありえない他の文字列(◆◇◆◇◆◇
)に置換してから
#key2 = strstr($tarline, "◆◇◆◇◆◇");
で対応することにし、それだとまったく問題がないことがわかりました。

#key + 1 では、つまり \t の直後の文字位置を取得しようとしているのですが、
これではだめなのでしょうか?

strstr() 関数でタブを検索すること自体がまずいのでしょうか?

長文で大変申し訳ありませんが、同じ現象に遭遇された方がいらっしゃったら教えてく
ださい。

[ ]
RE:01787 strstr 関数で教えてくださいNo.01788
TAKA さん 01/02/18 22:08
 
>はじめて投稿いたします。kyau と申します。

はじめまして。TAKA と申します。


>#key + 1 では、つまり \t の直後の文字位置を取得しようとしているのですが、
>これではだめなのでしょうか?
>
>strstr() 関数でタブを検索すること自体がまずいのでしょうか?

gettextの使用方法が間違っています。

//---- 第1のテストファイル(半端な位置にタブがない場合)
[\t]test
//---- ここまで

//---- 第2のテストファイル(半端な位置にタブがある場合)
 [\t]test
//---- ここまで
[\t]はタブ文字です。
第1と第2の違いは、タブの前に一文字(スペース)があるかない
かの違いです。

strstrでのタブの計算は1文字扱いになります。
gettextではワープロ的(タブは1文字で計算されない)に計算さ
れます。
今回は、それが問題になっています。

これ以降は、タブの設定が2の場合で説明します。
本来なら両方のテストファイルともgettextの第1引数で2を指定
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
しないといけないのですが、
^^^^^^^^^^^^^^^^^^^^^^^^^^
第1のテストファイルは、引数に1が指定され、
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
第2のテストファイルは、引数に2が指定されています。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
第1のテストファイルでは、間違った値が指定されますので、結果
は保証されないことがあるかもしれません。
message str( #key2 + 1 );
で確認してください。

タブの設定を1にすることが出来れば、今回のような問題は発覚し
なかったと思いますが。
タブの値を変更しないでも正常に動作するマクロを組むようにすれ
ば、今回のような問題はもう少し前に見つかっていたかもしれませ
んね。

ちなみに、Ver3.6とVer3.7はgettextに不具合があります。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
タブの計算に不具合がありますので、正常な値を指定しても、正常
に動作しません。

それ以外のバージョンでは間違った指定をしても、正常に動作する
かもしれませんが、やはり正しい値を指定すべきでしょう。

最新は、V3.08のβ版が、
http://hidemaru.xaxon.co.jp/software/bin/hm308b1.exe
にあります。

やり方は、いろいろあると思います。movetolineno(タブを一文字
で計算)で移動させてその位置から x の値を取得するとか。

gettextのエディタ的計算を行うものが、欲しいですね。

[ ]
RE:01787 strstr 関数で教えてくださいNo.01789
ひろ さん 01/02/19 10:46
 
 kyauさん今日は、ひろです。
> $eng = gettext(#key2 + 1, #y0, #x1, #y0); //$eng に化けた文字列が格納されるこ
> とがある。ここの #key + 1 という式が原因??
 おそらくそうです。
 gettext は行番号やカラム位置をワープロ的に数えた値を入れなければ
成りません。tabcount で現在タブ文字が表す文字数を表しているので、
$eng = gettext(#key2 + tabcount, #y0, #x1, #y0);
とすれば、上手くいくのではないでしょうか?

[ ]
RE:01789 strstr 関数で教えてくださいNo.01790
TAKA さん 01/02/19 12:48
 
>gettext は行番号やカラム位置をワープロ的に数えた値を入れなければ
>成りません。tabcount で現在タブ文字が表す文字数を表しているので、
>$eng = gettext(#key2 + tabcount, #y0, #x1, #y0);
>とすれば、上手くいくのではないでしょうか?

tabcountは固定値しか返しませんので、正確に位置指定することは
出来ません。

私の第1のテストファイルに対して
message str( #key2 + tabcount );
で容易に確認することが出来ます。本来は2でないといけないのが、
3になります。(タブの設定が2の場合)

[ ]
RE:01790 strstr 関数で教えてくださいNo.01791
ひろ さん 01/02/19 17:35
 
 TAKA さん今日は、ひろです。
> tabcountは固定値しか返しませんので、正確に位置指定することは
> 出来ません。
 確かにそうですねm(_|_)m、直前の文字のカラム位置によってタブ文字に
よってどれだけカーソル位置がずれるか異なるなので、もっと面倒な計算が
必要ですね。
 テストしていないので、自信がありませんが、
$eng = gettext(#key2 + tabcount - #key2 % tabcount, #y0, #x1, #y0);
とすれば良いのやら?

[ ]
RE:01791 strstr 関数で教えてくださいNo.01792
TAKA さん 01/02/19 19:50
 
>> tabcountは固定値しか返しませんので、正確に位置指定することは
>> 出来ません。
> 確かにそうですねm(_|_)m、直前の文字のカラム位置によってタブ文字に
>よってどれだけカーソル位置がずれるか異なるなので、もっと面倒な計算が
>必要ですね。
> テストしていないので、自信がありませんが、
>$eng = gettext(#key2 + tabcount - #key2 % tabcount, #y0, #x1, #y0);
>とすれば良いのやら?

最終的には、
[\t]test1[\t]test2[\t]test3[\t]test4
からデータを取得していきたいと思いますので、2つめのデータ以
降も正常に処理出来るようにもう少し工夫すれば、tabcountでも出
来なくはなさそうですね。
少し、めんどそうですが。

kyauさんは、タブを強制的に2にして、計算方法が2回に1回の確
立で間違うようにしていましたが、テストするときにはタブは4や
8でテストした方がプログラムミスが見つかりやすいですよ。
やり方は、movetolinenoを使用したり、tabcountを使用したり、ア
イデア次第ですので、頑張ってみて下さい。

[ ]
RE:01787 strstr 関数で教えてくださいNo.01793
kyau さん 01/02/19 23:54
 
TAKA さん、ひろさん、

早速のレス&有用なアドバイスありがとうございます。

思い切って質問してみてよかったです。ずっと試行錯誤していたので、、、。
アドバイスしていただいた方法、早速試してみようと思います。

本当はマクロをいじりながら、
もっともっと質問したいのですが、なかなか時間がもてず残念です。
また行き詰まったら(きっと行き詰まると思うので)相談させてください。
取り急ぎお礼を言わせていただきます。ありがとうございました^^

kyau

[ ]
RE:01792 strstr 関数で教えてくださいNo.01794
encodingshiftjis さん 01/02/20 00:07
 
最初の意図にフォーカスしていて、タブ位置にはあまり関連しませんが。

// x,y は表示に関連していて、行の折り返しにも影響を受けるから
// 表示整形ではない、データ処理の論理行ベースの処理には
// 向いていない。折り返し文字数を気にしながら。
// 少し表示座標から離れた書き方をすると, $tarline から直接取得する

                       $tarline = "12345表\t67890示";
  #midpoint =  strstr( $tarline, "\t");
$leftphrase = leftstr( $tarline, #midpoint);
$rightphrase=rightstr( $tarline, strlen( $tarline)-#midpoint-1);
menu $tarline, $leftphrase, $rightphrase;

// 別の方法としては gettext ではなくクリップボード系で取得する
 golinetop2; beginsel; searchdown "\t";
       copy; beginclipboardread; $leftphrase  = getclipboard;
 right;      beginsel; golineend2;
       copy; beginclipboardread; $rightphrase = getclipboard;
// searchdown の暴走などの検査if は省略しています。
menu $leftphrase, $rightphrase;
// 右の句\t左の句

//無理せずに、少し視点を広げるとスムーズです。

[ ]
RE:01794 strstr 関数で教えてくださいNo.01800
kyau さん 01/02/21 00:04
 
>最初の意図にフォーカスしていて、タブ位置にはあまり関連しませんが。
>
>// x,y は表示に関連していて、行の折り返しにも影響を受けるから
>// 表示整形ではない、データ処理の論理行ベースの処理には
>// 向いていない。折り返し文字数を気にしながら。
>// 少し表示座標から離れた書き方をすると, $tarline から直接取得する
>
>                       $tarline = "12345表\t67890示";
>  #midpoint =  strstr( $tarline, "\t");
>$leftphrase = leftstr( $tarline, #midpoint);
>$rightphrase=rightstr( $tarline, strlen( $tarline)-#midpoint-1);
>menu $tarline, $leftphrase, $rightphrase;
>
>// 別の方法としては gettext ではなくクリップボード系で取得する
> golinetop2; beginsel; searchdown "\t";
>       copy; beginclipboardread; $leftphrase  = getclipboard;
> right;      beginsel; golineend2;
>       copy; beginclipboardread; $rightphrase = getclipboard;
>// searchdown の暴走などの検査if は省略しています。
>menu $leftphrase, $rightphrase;
>// 右の句\t左の句
>
>//無理せずに、少し視点を広げるとスムーズです。

なるほど、、、目からうろこが落ちるおもいです。これぜひ使わせていただきます。
ありがとうございました。

[ ]