バイト配列の途中に代入するには

解決


固まる  2004-05-26 10:15:44  No: 9134

おせわになっております。
年月日時分秒をパック10進数形式のバイト配列で返す関数の戻り値を、
呼び出し側で、バイト配列の途中に代入するようなことはできますでしょうか。
また、関数の書き方についても、怪しい点があれば教えてください。

【呼び出し側】
var
  B:array[0..7] of byte;
begin

  B[0]    := $FF;
  //↓こんな感じの代入がやりたいのですが…エラーになります。
  B[1..6] := PFNowTo6Byte(); 
  B[7]    := $FF;

  showmessage(
       '■' + IntToHex(result[0],2)
      + '-' + IntToHex(result[1],2)
      + '-' + IntToHex(result[2],2)
      + '-' + IntToHex(result[3],2)
      + '-' + IntToHex(result[4],2)
      + '-' + IntToHex(result[5],2)
      + '-' + IntToHex(result[6],2)
      + '-' + IntToHex(result[7],2) + '■'
  );

// 2004/05/25 12:30:58 の場合
//「■FF-04-05-25-12-30-58-FF■」と表示させたいのです

────────────────────────
//※TByteArray: array of Byte;
function TForm1.PFNowTo6Byte: TByteArray;
var
  UsStr :String;
  UsInt :Integer;
begin
  UsStr := FormatDateTime('yymmddhhnnss',Now);
  Val( '$' + Copy(UsStr, 1,2), result[0], UsInt);
  Val( '$' + Copy(UsStr, 3,2), result[1], UsInt);
  Val( '$' + Copy(UsStr, 5,2), result[2], UsInt);
  Val( '$' + Copy(UsStr, 7,2), result[3], UsInt);
  Val( '$' + Copy(UsStr, 9,2), result[4], UsInt);
  Val( '$' + Copy(UsStr,11,2), result[5], UsInt);
end;
────────────────────────


jok  2004-05-26 14:14:53  No: 9135

こんな感じです。

type
TByteArray = array of Byte;

function PFNowTo6Byte: TByteArray;
var
  UsStr :String;
  UsInt :Integer;
begin
  SetLength(result,6);
  UsStr := FormatDateTime('yymmddhhnnss',Now);
  Val(Copy(UsStr, 1,2), result[0], UsInt);
  Val(Copy(UsStr, 3,2), result[1], UsInt);
  Val(Copy(UsStr, 5,2), result[2], UsInt);
  Val(Copy(UsStr, 7,2), result[3], UsInt);
  Val(Copy(UsStr, 9,2), result[4], UsInt);
  Val(Copy(UsStr,11,2), result[5], UsInt);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  B:TByteArray;
begin
  B := PFNowTo6Byte;
  Label1.Caption := Format('■FF-%.2d-%.2d-%.2d-%.2d-%.2d-%.2d-FF■',
                           [B[0],B[1],B[2],B[3],B[4],B[5]]);
end;


jok  2004-05-26 14:24:49  No: 9136

おっと

> バイト配列の途中に代入するには

でしたね。地道に代入すると

type
TByteArray = array of Byte;

function PFNowTo6Byte: TByteArray;
var
  UsStr :String;
  UsInt :Integer;
begin
  SetLength(result,6);
  UsStr := FormatDateTime('yymmddhhnnss',Now);
  Val(Copy(UsStr, 1,2), result[0], UsInt);
  Val(Copy(UsStr, 3,2), result[1], UsInt);
  Val(Copy(UsStr, 5,2), result[2], UsInt);
  Val(Copy(UsStr, 7,2), result[3], UsInt);
  Val(Copy(UsStr, 9,2), result[4], UsInt);
  Val(Copy(UsStr,11,2), result[5], UsInt);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  B:TByteArray;
  C:array [0..7] of Byte;
  i:integer;
begin
  B := PFNowTo6Byte;
  C[0] := $FF;
  for i := 1 to 6 do C[i] := B[i-1];
  C[7] := $FF;
  Label1.Caption := Format('■%.2x-%.2d-%.2d-%.2d-%.2d-%.2d-%.2d-%.2x■',
                           [C[0],C[1],C[2],C[3],C[4],C[5],C[6],C[7]]);
end;


jok  2004-05-26 18:32:41  No: 9137

> バイト配列の途中に代入するには

ですが、上の

for i := 1 to 6 do C[i] := B[i-1];

のかわりに

Move(B[0],C[1],6);

も使えますね。


頑固ひとスジふたスジ  2004-05-26 19:24:48  No: 9138

ひとスジ : 「動的配列って ホントはポインタだってこと知っとった?」
ふたスジ : 「知らんかった〜」
ひとスジ : 「だからこんなことできるの知っとった?」
ふたスジ : 「知らんかった〜」

type
  TByteArray = array of Byte;

function PFNowTo6Byte(var C: TByteArray): TByteArray;
var
  UsStr : String;
  UsInt : Integer;
begin
  UsStr := FormatDateTime('yymmddhhnnss', Now);
  Val('$'+ Copy(UsStr, 1,2), C[1], UsInt);
  Val('$'+ Copy(UsStr, 3,2), C[2], UsInt);
  Val('$'+ Copy(UsStr, 5,2), C[3], UsInt);
  Val('$'+ Copy(UsStr, 7,2), C[4], UsInt);
  Val('$'+ Copy(UsStr, 9,2), C[5], UsInt);
  Val('$'+ Copy(UsStr,11,2), C[6], UsInt);
  result := TByteArray(@C[1]);             // Cの一部分をBにする
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  B: TByteArray;
  C: TByteArray;
begin
  SetLength(B, 6);
  SetLength(C, 8);
  B := PFNowTo6Byte(C);
  C[0] := $FF;
  C[7] := $FF;
  Label1.Caption := Format('■%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x■',
                           [C[0],C[1],C[2],C[3],C[4],C[5],C[6],C[7]]);
  Label2.Caption := Format('■FF-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-FF■',
                           [B[0],B[1],B[2],B[3],B[4],B[5]]);
end;

ふたスジ : 「ンなら、オマエのお菓子 オレが食べちゃったの知っとった?」
ひとスジ : 「知らんかった〜」


jok  2004-05-26 20:04:34  No: 9139

> ひとスジ : 「動的配列って ホントはポインタだってこと知っとった?」

そうですね。string 型に似てますよね。

> result := TByteArray(@C[1]);             // Cの一部分をBにする

なるほど、これは値を代入するのではなく、参照を代入する感じですね。
だとすると、長い配列の一部を受け取る短い配列の

SetLength(B, 6);

はいりませんね。実体は必要ないですから。参照が代入されている様子を
見てみましょう。

procedure TForm1.Button1Click(Sender: TObject);
var
  B,C:TByteArray;
begin
  SetLength(C,3);
  C[0] := $FF;
  C[1] := $AA;
  C[2] := $FF;

  B := TByteArray(@C[1]);
  Memo1.Lines.Add(IntToHex(B[0],2));

  C[1] := $BB;
  Memo1.Lines.Add(IntToHex(B[0],2));
end;

こんなふうにすると、Memo1 には

AA
BB

と表示されて、B[0] が C[1] と同じ場所を参照しているのが分かりますね。
わたしの回答は「代入」を値のコピーとして解釈したものです。

それから、今日の日付は26日ですけど、

> Val('$'+ Copy(UsStr, 5,2), C[3], UsInt);

にすると16進の26、つまり10進の38が C[3] に代入されますね。
表示のとき、16進数にしているので見かけは同じですが、十進数として
格納し、表示も10進数表示にするのが理にかなっているように思います。


固まる  2004-05-27 02:45:02  No: 9140

ありがとうございました。
関数をやめて以下のような手続きにしました。

【呼び出し側】
var
  DAT   :array[120] of Byte;
  UsIdx :Integer;
Begin
  UsIdx := 0;
  //…
  UsIdx := UsIdx + 14;
  Set_Now6Byte( DAT, UsIdx);

────────────────────────────────
// 年月日時分秒6バイト
procedure TMain_F.Set_Now6Byte(var ArByt: TByteArray; ArIdx: integer);
var
  UsStr : String;
  UsInt : Integer;
begin
  UsStr := FormatDateTime('yymmddhhnnss', Now);
  Val('$'+ Copy(UsStr, 1,2), ArByt[ArIdx + 0], UsInt);
  Val('$'+ Copy(UsStr, 3,2), ArByt[ArIdx + 1], UsInt);
  Val('$'+ Copy(UsStr, 5,2), ArByt[ArIdx + 2], UsInt);
  Val('$'+ Copy(UsStr, 7,2), ArByt[ArIdx + 3], UsInt);
  Val('$'+ Copy(UsStr, 9,2), ArByt[ArIdx + 4], UsInt);
  Val('$'+ Copy(UsStr,11,2), ArByt[ArIdx + 5], UsInt);
end;


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

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






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