|
15番会議室「FAQ編纂委員会」に寄せられた「よくある質問の答え」
[Q]
TStream や TFileStream を文字列の読み書きに使う場合、この、Readメソッ
ド、Writeメソッドは、コンソール、あるいは、テキストファイル入出力のも
のと少し違います。例えば、
const
aString: String='これはShortString'#13#10;
MemoryStream.Write(aString,Length(aString));
で、書き込まれたものを見ると、先頭に何か記号1バイトがあり、#13まで
しか書き込まれません。また、
var
pcStr: PChar;
MemoryStream.Write(pcStr,StrLen(pcStr));
では、期待通りに書き込まれません。
[A]
StreamのWriteメソッドは、引数の変数の先頭バイトから書き込みますから
ShortStringの場合、先頭バイトaString[0]の文字数バイトが書き込まれます。
このために、そこから1バイトずつ文字数だけ読んだとき、1バイトずれて、
最後の#10が書き込まれなくなったのです。
PCharの場合は、「逆参照」(注)読み書きが必要です(これは、SBORLAND
で、昨年、謎の全知師さんに教わりました)。つまり、
MemoryStream.Write(pcStr^,StrLen(pcStr));
{末端ヌルは書き込まれません。末端ヌルまででしたら、もう1バイト増
やして、}
(* MemoryStream.Write(pcStr^,StrLen(pcStr)+1); {です} *)
なお、Write、Readメソッドと、Sizeof(引数)の関係に関して、後ろの
>[FAQ]TStream、Sizeof、文字列長さ
をごらん下さい。
(注)関数の引数に使う変数が値を取得するのに、ポインタ変数 px をその
まま用いて、値を取得するのが「参照渡し(call by reference)」で、ポイン
タ変数 px に何らかの演算子を付けて(TP あるいは Delphi の場合には
px^)、ポインタ変数が示すメモリー番地に保持されている値を取得するのが
「値渡し(call by value)」でした。
うっかり pcStr^ を「参照」と書いてしまいましたが、この場合「逆参照
(デリファレンス−dereference ?)」というのが正しいようです。トム・スワ
ン著「Turbo Pascal for Windows プログラミング技法」には、
type
TBuffer=array[0..1023] of word;
PBuffer=^TBuffer;
var
BP: TBuffer;
Buffer: TBuffer;
として、
BP:=@Buffer;
N:=BP^[44];
と挙げたあと、
「キャレット(^)を使ったBPの参照は、コンパイラに対してBPそのものの値
~~~~
ではなく、BPで示されるアドレスの項目にアクセスすることを指示します。」
とありますが、Delphi の最新2著、サビエル・パチェコらの「Delphi プログ
ラミング技法 Vol.1」と、チャールズ・カルバート「Delphi 2.0J 32bit パ
ワープログラミング」では、「逆参照」と、はっきり書いていました。
TP あるいは Delphi では、多くの場合、この、逆参照キャレット(^)を使
わないでも値渡しができるようになっているのですが。
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum FDELPHIに寄せられる質問の中から、よくある質問への回答を FDELPHIのメンバーがまとめたものです。 したがって、これらの回答はボーランド株式会社がサポートする公式のものではなく、掲示されている内容についての問い合わせは受けられない場合があります。
Copyright 1996-1998 Delphi Users' ForumFAQ編纂委員会
|