> バイナリデータを文字列として処理することに無理があるので、 by ANTARES さん
よくよく考えれば仰る通りです。
文字列に文字列操作以外の処理を行っているので、すでにそれは文字列ではない、
バイナリデータだ、文字列を受け取る命令や関数には絶対に渡してはならない、
何かしたい時は全部自前で処理しなければならない、という扱いをするべきですね。
「文字列」を表示する mes 命令を使って表示しようとした事自体、間違っていたという事ですね。
-------------------------- 以下、余談 -------------------------------
私も ANTARES さんが考えるように、ヌル文字の直前に 2 byte 文字の
1 byte 目となるデータが入ってしまった事が、この問題が発生した
原因のひとつではないかと思っています。
しかし、今回の件ではこれだけでは説明が付かない事が起きているのもまた事実です。
以下は、Niko さんのスクリプトにおける test ルーチン実行後の string を、
ANTARES さんのスクリプトによる方法でダンプした物です。
バイナリデータ 対応する文字
83 66 85 5B 87 6C 88 5A 8B 6E 8D 63 8F 74 90 62 デ・㌫・杵皇春臣
93 76 95 6B 97 7C 98 6A 9B 7E 9D 73 9F 84 A0 72 砺斌慾亘宀捏氛.r
A3 86 A5 7B A7 8C A8 7A AB 8E AD 83 AF 94 B0 82 」・{ァ肩zォ鹿Ρ伐.
00 82 51 83 65 83 58 83 67 82 51 0D 0A 81 40 81 .2テスト2..
40 81 40 20 81 40 83 65 83 58 83 67 82 52 83 65 テスト3テ
83 58 83 67 82 52 83 65 83 58 83 67 82 52 00 スト3テスト3.
48 byte 目、最初のヌル文字 (0x00) の前に、shift-jis における 2 byte 文字
の 1 byte 目である 0x82 が来ています。これによって、ヌル文字が 1 文字の
全角日本語の一部とみなされてしまった、というのは十分考えられる事です。
しかし、このヌル文字をそう解釈したのであれば、その直後の「2テスト2」も
画面に出力されなければならないはずです。
ところが、実際にはそうではなく、「2テスト2」の後の改行 (0x0d 0x0a) 以降しか
出力には現れていません。これは一体どういう事なのでしょう?
試しに string に格納されていた改行を取っ払って、代わりに ' ' を 2 byte 入れてみた所、
なんと正常に表示されました!!
(' ' を代わりに入れたのは、test ルーチンが文字列長で生成データに影響を与えるからです。)
ですから、今回の件にはこの改行も一枚噛んでいる可能性があります。
今はどうして「2テスト2」が消えてしまうのかは分かりませんが、とりあえずご報告を。
なお、ANTARES さんの「ヌル文字が 2 byte 文字に解析されちゃうなら、その次の byte を
ヌル文字にしちゃえ~作戦」は、うまく動作しませんでした。
string のバッファのヌル文字以降の領域すべてをゼロクリアしても同様です。
string 自体にはもう「テスト3」の欠片も残っていないのに「テスト3」が出力されるという事は、
これはどうやら、HSP のメモリ管理の仕組みも理解しないと完全な原因の特定は出来そうに無いですね。
まぁ、こういう底なし沼みたいなドロドロした部分に足を踏み入れたくないなら、
素直に文字列でない物を mes なんかで表示しないって事になりますね。
さらに余談で、私は上記のレスで、string をファイルに書き出した場合
「テスト3」が消えたと述べましたが、その理由について。
私はそのとき notesave を使って書き出したのですが、これは内部的に
repeat
c = peek(src,cnt) ; src は書き込むデータを保持した変数
if (c == 0): break
poke dst,cnt,c ; dst はファイルと思ってください
loop
こんな感じの処理が行われているからだと思います。
これなら 1 byte 文字だろうが 2 byte 文字だろうが関係なく処理されます。
Niko さんの mesbox についても検証してみましたが、あれはあれでさらに余計な現象が
起きているので、他の要因がある事になります。うへぇ~…
ホントにドロドロしてますね。
触らぬ神にたたり無しという言葉が身に染みて分かります。