喫茶XRAYトップページ

[スレッド全体
]

[12026] PAnsiCharをStrPCopy関数で使用返信 削除
2018/7/11 (水) 06:27:25 Mr.XRAY
Unicode 版の Delphi で PAnsiChar 型の文字列を StrPCopy 関数で使用する
場合は,次のように,uses に AnsiStrings を追加して明示的に AnsiStrings を
記述しみてください.

implementation

uses
  AnsiStrings;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  LPAnsiChar  : PAnsiChar;
begin
  LPAnsiChar := AllocMem(200);
  try
    AnsiStrings.StrPCopy(LPAnsiChar, '日本語 ABC 文字列');
    Memo1.Lines.Add(string(LPAnsiChar));
  finally
    FreeMem(LPAnsiChar);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  LAnsiString : AnsiString;
  LPAnsiChar  : PAnsiChar;
begin
  LAnsiString := '日本語 ABC 文字列';
  LPAnsiChar  := AllocMem(Length(LAnsiString) + 1);
  try
    AnsiStrings.StrPCopy(LPAnsiChar, LAnsiString);
    Memo1.Lines.Add(string(LPAnsiChar));
  finally
    FreeMem(LPAnsiChar);
  end;
end;



[12032] Re:PAnsiCharをStrPCopy関数で使用返信 削除
2018/7/11 (水) 11:58:59 Mr.XRAY
> AnsiStrings を追加して明示的に AnsiStrings を

Move 関数を使ってしまう手もあります.
Move 関数を使用する場合は uses に AnsiStrings は不要です.

※ Length(Ansi文字変数) はバイト数を返します.

procedure TForm1.Button3Click(Sender: TObject);
var
  LAnsiString : AnsiString;
  LPAnsiChar  : PAnsiChar;
begin
  LAnsiString := '日本語 ABC 文字列';
  LPAnsiChar  := AllocMem(Length(LAnsiString) + 1);
  try
    Move(LAnsiString[1], LPAnsiChar^, Length(LAnsiString));
    Memo1.Lines.Add(string(LPAnsiChar));
  finally
    FreeMem(LPAnsiChar);
  end;
end;


[12036] Move関数の引数返信 削除
2018/7/12 (木) 06:22:50 Mr.XRAY
Move 関数には引数が 3 つあります.
第 2 の引数はコピー先です.
したがって,変数名を使用する必要があります.
以下の動作確認は Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 です.

[System.Move - RAD Studio API Documentation]
http://docwiki.embarcadero.com/Libraries/XE5/ja/System.Move


//=============================================================================
//  Move関数
//  第1引数 コピー元
//  第2引数 コピー先
//  第3引数 コピーするバイト数
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
 LAnsiString  : AnsiString;
 LAnsiCharArr : array [0..25] of AnsiChar;
begin
  LAnsiString := '日本語 ABC 文字列';

  FillChar(LAnsiCharArr, Length(LAnsiCharArr), #0);
  Move(LAnsiString[1], LAnsiCharArr, Length(LAnsiString));

  Memo1.Lines.Add(LAnsiCharArr);
end;



[12044] 変数の初期化とメモリ領域の確保返信 削除
2018/7/13 (金) 06:17:50 Mr.XRAY
>   FillChar(LAnsiCharArr, Length(LAnsiCharArr), #0);
>   Move(LAnsiString[1], LAnsiCharArr, Length(LAnsiString));


Move 関数によるコピーでは,コピー先が Char(AnsiChar) 型の静的配列の場合,
FilllChar で #0 (つまり Null 文字) で初期化しないと,
文字列の後ろに文字化けしたような「ゴミ」が付きます.

# 静的配列というのは,変数の定義の時に文字数やバイト数分のメモリ領域を
# 確保する配列のことです.
# 動的配列では SetLength でメモリを確保できます.
# PChar(PAnsiChar) の変数は AllocMem や StrAlloc でメモリ領域を確保します.
# コピー先のメモリ領域が確保されていない状態で Move 関数や StrPCopy 関数を
# 実行すると例外が発生します.

↑ 既に提示したコードで確認してください.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82