文字列処理がおかしいNo.02613
三宅 さん 03/08/05 09:02
 
// 同じ(はずの)文字列から midstr() したものが等しいと判定されない
// (その文字の ascii() は、等しいと判定される)

$s1 = "粘";
$s2 = $s1;

#cx = 0;
$ss1 = midstr( $s1, #cx, 1 );
$ss2 = midstr( $s2, #cx, 1 );

if ($ss1 == $ss2) {  //これは等しいと判定されない
 message "equal";
} else {
 message "not equal";
}

#c1 = ascii($ss1);
#c2 = ascii($ss2);

if (#c1 == #c2) {  //これは等しいと判定される
 message "equal";
} else {
 message "not equal";
}

endmacro;

環境:Windows98, Ver.4.00β13(Ver.3.19 でも起こる)

[ ]
RE:02613 文字列処理がおかしいNo.02617
アルビレオ さん 03/08/05 11:12
 
秀丸ユーザーのアルビレオです。

>// 同じ(はずの)文字列から midstr() したものが等しいと判定されない
>// (その文字の ascii() は、等しいと判定される)

仕様としては「文字列の内容の判定に比較演算子を使うことはできない」という
ことになると思います。

文字列の内容が同じかどうかを判定するには、

if (strlen($ss1) == strlen($ss2) && strstr($ss1, $ss2) == 0) {
 message "equal";
} else {
 message "not equal";
}

という方法が使えます。


○秀まるおさんへ
文字列に対して比較演算子を使った場合はエラーとした方がいいような気がしま
す。

マクロヘルプの「文字列の演算としては,+だけが使えます」という表現だと、
比較演算子や論理演算子は`演算'ではないと解釈してしまう場合があるというこ
とだと思います。
代案としては
  文字列に対する演算子としては,+だけが使えます。
とするか、最後の方に
  == や > などの比較演算子や,&& や ! などの論理演算子は
  {正しい結果になりません|エラーとなります}。
と追記してみてはどうでしょうか。

[ ]
RE:02617 文字列処理がおかしいNo.02620
三宅 さん 03/08/05 12:56
 
>仕様としては「文字列の内容の判定に比較演算子を使うことはできない」という
>ことになると思います。

 なるほど、マクロヘルプをちゃんと読めば、そういうことなのですね。
 ありがとうございます。

>○秀まるおさんへ
>文字列に対して比較演算子を使った場合はエラーとした方がいいような気がします。
> ・・・
>代案としては ・・・

 できれば、ご検討をお願いします。

[ ]
RE:02617 文字列処理がおかしいNo.02624
IKKI さん 03/08/05 15:04
 
IKKI です。

> if ($ss1 == $ss2) {  //これは等しいと判定されない
> if (#c1 == #c2) {  //これは等しいと判定される

手元の環境では両方とも等しいと判定されました。
(秀丸4.0β13 + Win2000 SP4)


> 仕様としては「文字列の内容の判定に比較演算子を使うことはできない」という
> ことになると思います。

これは昔からそうだったのでしょうか?
#だとすると、公開中のマクロが全滅する可能性が……(汗


> ○秀まるおさんへ
> 文字列に対して比較演算子を使った場合はエラーとした方がいいような気がしま
> す。

むしろ、比較演算子で文字列の内容比較が正しくできるようにしていただきたいとこ
ろです。

よろしくお願いいたします。

[ ]
RE:02620 文字列処理がおかしいNo.02629
Iranoan さん 03/08/05 16:45
 
 秀丸担当さん、三宅さん、アルビレオさん今日は、Iranoan です。
> >仕様としては「文字列の内容の判定に比較演算子を使うことはできない」という
> >ことになると思います。
>
>  なるほど、マクロヘルプをちゃんと読めば、そういうことなのですね。
 本当にそうなのかなあ〜。ヘルプを読むとそう読めなくも無いですが、
「==」ではなく「<」「>」についてですが、秀丸担当さんの過去の発言に、
http://hidemaruo.dip.jp:81/hidesoft/hidesoft_2/x09926.html#9944
> >このことについて、秀丸Q&A集会議室にて
> >Win32API の lstrcmp() を使っているのではないかとの
> >指摘がありました。
> >
> >これは正しいですか?
>
> その通りです。
> lstrcmp()を使っているので、その通りのルールになっています。
とあります。このことから比較演算子を使えない訳ではないと思います。また
http://www.maruo.co.jp/hidesoft/8/ に秀まるおさんご自身が、比較演算子
を利用したマクロを何度も投稿されています(^^)。

 個人的には 2 バイト文字をその途中で切り取り、そのまま処理し続ける事
が仕様外で、動きが保証されていない (不定) ということだと思いますけど。

 秀丸担当さんの正式なコメントが頂きたいですね。

[ ]
RE:02629 文字列処理がおかしいNo.02645
秀丸担当 さん 03/08/06 15:29
 

文字列の比較演算子は、<= >= < > == != が使えます。

試しに問題のマクロを実行してみたところ、equalになりました。

> 個人的には 2 バイト文字をその途中で切り取り、そのまま処理し続ける事
>が仕様外で、動きが保証されていない (不定) ということだと思いますけど。

確かにこのままでは2バイト文字の半分だけで変数に入っている状態でlstrcmp
()しています。
ですが、こちらで確認したところでは、この状態でも問題ありませんでした。

[ ]
RE:02645 文字列処理がおかしいNo.02648
Iranoan さん 03/08/06 16:51
 
 秀丸担当さん今日は、Iranoan です。
> 確かにこのままでは2バイト文字の半分だけで変数に入っている状態でlstrcmp
> ()しています。
 OS に依存する物としては、
#n = existfile("<>");
http://hidemaruo.dip.jp:81/hidesoft/hidesoft_2/x06898.html#6961
が有ります。←既に修正されていたりして(^^;。

 同様に 95/NT 系で lstrcmp() 関数の動作が変わるということでは?
Windows98 の私の環境でも再現しています。

 まあこれは「2バイト文字の半分だけで変数に入っている状態」という特殊
な状況なので、仕様で良いと思いますけど。

[ ]
RE:02648 文字列処理がおかしいNo.02666
三宅 さん 03/08/06 23:32
 
>> 確かにこのままでは2バイト文字の半分だけで変数に入っている状態でlstrcmp
>> ()しています。

 あ、そういうことだったんですか。
 マクロヘルプに「s1の左側からn1番目のn2文字」とあったのを、てっきり
2バイト文字も1文字に数えるんだと思っちゃってました。

 その意味では、議論の流れからは逸れますが、私の見逃しでなければ、
midstr などのマクロヘルプに一言注記して頂ければありがたいかなと思います。

 お騒がせしてしまいましたが、みなさん、どうもありがとうございました。

[ ]
RE:02624 文字列処理がおかしいNo.02671
アルビレオ さん 03/08/07 02:05
 
アルビレオです。

>手元の環境では両方とも等しいと判定されました。

どうも C のことが頭にあったようで…
いいかげんなことを書いてすみませんでした。

[ ]
RE:02671 文字列処理がおかしいNo.02672
IKKI さん 03/08/07 02:21
 
IKKI です。

> > ○秀まるおさんへ
> > 文字列に対して比較演算子を使った場合はエラーとした方がいいような気がしま
> > す。
>
> むしろ、比較演算子で文字列の内容比較が正しくできるようにしていただきたいとこ
> ろです。

すみません、私もあせって早とちりして↑変なこと書いてしまいました。

いずれにせよ midstr() 等の2バイト文字対応(ヘルプに書く、2バイト文字も1文字
と見なす別関数を作る、など何らかの措置)は必要だと思いますけれど。

[ ]
RE:02648 文字列処理がおかしいNo.02698
秀丸担当 さん 03/08/08 11:43
 

> 同様に 95/NT 系で lstrcmp() 関数の動作が変わるということでは?
>Windows98 の私の環境でも再現しています。

95/NT系で動作が違うことを確認したので、とりあえず95系でも動作が同じにな
るように(イコールになるように)修正します。

[ ]