SetLengthで確保し、余ったものをなくすには?


たまよ  2009-08-17 05:56:35  No: 35431

瞬殺される質問かもしれませんが・・・、

SetLength(s,100);
s[1] := 'a';
s[2] := ' ';
s[3] := 'b';
ShowMessage(s);

すると、100文字分表示されますよね?
これを'a b'だけにしたいのです。

Lengthで文字数を調べて、おしりからループ。
初めて文字があったらフラグを立てて、そこから文字のコピー。
もしくは、配列の切り取り・・・、みたいな事をするのでしょうか?

関数があったら教えてください。
delphi6です。


たまかい!(←ツッコミ)  2009-08-17 09:53:08  No: 35432

そんな悩まなくても...
SetLength(s,100);として3文字だけ指定した場合、その後ろには何もないと思うのは間違い。
ゴミデータが入ることがあるし、たとえ残りが全部Null文字で埋っていたとしても、
Length(s);の値は100になる。
もし3文字だけに切り取りたいなら、
SetLength(s, 3);
と3文字分の長さに再割り当てするだけ。


たまよ  2009-08-17 10:16:02  No: 35433

私も、3文字だけなら、3文字切り取りますよ。^^
文字数は、不定でお願いします。

Length(s)で、文字数を調べて、100ならs[100]が入っているかどうか、s[99]が入っているかどうか・・・、を調べていくしかないのかなー?と。
1からだと、空白があるとまずいので。

でも、ゴミデータって、指定した文字以外に入ることがあるんですか?
メモリーとかの関係なんでしょうか?
じゃー、ほかの方法を考えないとダメですか。

ちなみに、たまよは本名です。(●`・(エ)・´●)プンプンッ


KHE00221  2009-08-17 11:17:48  No: 35434

s[4] := Char(0); が可能なら ShowMessage(PChar(s));


igy  2009-08-17 19:14:40  No: 35435

s が動的配列ではなく、文字列なら、以下のような感じでどうですか?

procedure TForm1.Button1Click(Sender: TObject);
var
    S: String;
begin
    SetLength(s,100);
    S := StringOfChar(' ', 100);
    s[1] := 'a';
    s[2] := ' ';
    s[3] := 'b';
    ShowMessage(TrimRight(s));
end;


Mr.XRAY  2009-08-17 19:39:47  No: 35436

>文字数は、不定でお願いします。

自分で代入すべき文字数が判断できない,ということですか?
う〜む.

>ゴミデータって、指定した文字以外に入ることがあるんですか?

入るのではなく,既に値(データ)があるメモリ領域に確保されるということです.
SetLength(s,100);
とすると,この分は,他でつかっちゃいけないよ,となります.

実行済みのプロシージャー等の実行部分のメモリは不要となり使用可能となります(解放されると言います).
またFreeメソッドやReleaseメソッドでは,該当部分のメモリが解放されます.
つまり,他で使ってもいいよ.となります.
でも,その部分のメモリ領域が初期化されるわけではありません.
そのため,このデータがゴミとして,新たに確保されたメモリに残ることになります.

初期化したいのであれば,以下のように,既にあるレスのように,Null終端文字列で
扱えるように,初期化する方法もあります.
(Delphi 6ならば動作すると思います)

procedure TForm1.Button1Click(Sender: TObject);
var
    S : String;
begin
    SetLength(s,100);
    FillChar(S[1],Length(s)-1,0);
    s[1] := 'a';
    s[2] := ' ';
    s[3] := 'b';
    //ShowMessage(Trim(s)); でも可
    ShowMessage(PChar(s));
end;

どんな目的で,s[1] := 'a'; のようにするのかは分かりませんが,
単に文字の代入でしたら,以下の方法も考えられると思います.
これでしたら,2バイト文字もそのまま扱えます.
もっとも,この場合,文字の代入を自動でやるとしたら,ループで回すことになる
かも知れませんので,あらかじめ,代入文字数を知る必要があるかも知れませんね.
代入する対象の文字を,どこから持ってくるのかというのも関係するかも知れません.

procedure TForm1.Button1Click(Sender: TObject);
var
    S : String;
begin
    s := '';
    s := s + 'a';
    s := s + ' ';
    s := s + 'b';
    ShowMessage(s);
end;


Mr.XRAY  2009-08-17 19:40:47  No: 35437

> S := StringOfChar(' ', 100);

こちらの方がいいかも知れませんね.


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加