Delphi 将字符串分配给字符数组

Delphi 将字符串分配给字符数组,delphi,Delphi,问题一 我有 var example : array[0..15] of char; 我想把输入值赋给那个变量 example := inputbox('Enter Name', 'Name', ''); 在highscores单元中,我有记录和数组 type points = record var _MemoryName : array[0..15] of char; _MemoryScore : integer; end; var rank : array[1..3] of

问题一

我有

var example : array[0..15] of char;
我想把输入值赋给那个变量

example := inputbox('Enter Name', 'Name', '');

在highscores单元中,我有记录和数组

type
points = record
var
  _MemoryName : array[0..15] of char;
  _MemoryScore : integer;
end;

var
rank : array[1..3] of points;

返回->(186):
E2010不兼容类型:“字符数组[0..15]和“PWideChar”

var s: string;
 a: packed array[0..15] of char;

             s := InputBox('caption', 'Caption', 'Caption');
             FillChar(a[0], length(a) * sizeof(char), #0);
             Move(s[1], a[0], length(a) * sizeof(char));
      scores.rank[1]._MemoryName := <<tried both s and a>> ;
vars:string;
a:字符的压缩数组[0..15];
s:=输入框('caption','caption','caption');
FillChar(a[0],长度(a)*sizeof(char),#0);
移动(s[1],a[0],长度(a)*sizeof(char));
分数。排名[1]。_MemoryName:=;

返回
(189):E2008不兼容的类型

安德烈亚斯已经回答了问题1

问题2

我会安排您的事件处理程序调用另一个方法:

procedure TForm5.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  RespondToEditControlKeyPress;
end;
这样您就可以直接调用
RespondToEditControlKeyPress

我猜您希望不带参数地调用它,因为您希望在修改编辑控件的文本时运行代码。您可以使用
OnChange
事件来代替。而且可能是
OnChange
更合适,因为按键并不是将文本输入编辑控件的唯一方式



顺便说一下,在堆栈溢出问题上,最好一次只问一个问题。

Andreas已经介绍了问题1

问题2

我会安排您的事件处理程序调用另一个方法:

procedure TForm5.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  RespondToEditControlKeyPress;
end;
这样您就可以直接调用
RespondToEditControlKeyPress

我猜您希望不带参数地调用它,因为您希望在修改编辑控件的文本时运行代码。您可以使用
OnChange
事件来代替。而且可能是
OnChange
更合适,因为按键并不是将文本输入编辑控件的唯一方式



顺便说一下,在堆栈溢出问题上,最好一次问一个问题。

问题一

有很多方法。一是:

procedure TForm1.FormCreate(Sender: TObject);
var
  s: string;
  a: packed array[0..15] of char;
begin
  s := InputBox(Caption, Caption, Caption);
  assert(length(s) <= 16);
  FillChar(a[0], length(a) * sizeof(char), #0);
  Move(s[1], a[0], length(s) * sizeof(char));
end;
这不管用。不能将数组视为字符串;特别是,不能像这样分配静态数组(
a:=b

相反,你必须做一些像

Move(b[0], a[0], length(a) * sizeof(char));
…或者一次循环并复制一个值。但是,如果声明静态数组类型,则上述简单赋值(
a:=b
)确实有效:

type
  TChrArr = packed array[0..15] of char;

procedure TForm4.FormCreate(Sender: TObject);
var
  a: TChrArr;
  b: TChrArr;
begin
  b := a;
end;

问题一

有很多方法。一是:

procedure TForm1.FormCreate(Sender: TObject);
var
  s: string;
  a: packed array[0..15] of char;
begin
  s := InputBox(Caption, Caption, Caption);
  assert(length(s) <= 16);
  FillChar(a[0], length(a) * sizeof(char), #0);
  Move(s[1], a[0], length(s) * sizeof(char));
end;
这不管用。不能将数组视为字符串;特别是,不能像这样分配静态数组(
a:=b

相反,你必须做一些像

Move(b[0], a[0], length(a) * sizeof(char));
…或者一次循环并复制一个值。但是,如果声明静态数组类型,则上述简单赋值(
a:=b
)确实有效:

type
  TChrArr = packed array[0..15] of char;

procedure TForm4.FormCreate(Sender: TObject);
var
  a: TChrArr;
  b: TChrArr;
begin
  b := a;
end;

用于快速将字符串类型值复制到字符类型值数组中。我建议使用如下小辅助函数:

procedure StrToCharArray( inputStr:String; var output; maxlen:Integer);
type
    ArrayChar = Array[0..1] of Char;
begin
  StrLCopy( PChar(@ArrayChar(output)[0]),PChar(inputStr),maxlen);
end;
每次调用时,传入要复制的最大长度。请记住,如果缓冲区长度为15,则应传入14作为maxlen,这样,如果要始终终止字符串,就可以为终止nul字符留出空间:

StrToCharArray( UserInputStr,  MyRecord.MyField,  14 );
此函数将确保复制到记录中的数据以null结尾,前提是这是您想要的。请记住,在固定长度的字符数组中,由您决定规则是什么。空终止?完全填充空格或空字符。。。。字符串和字符数组非常不同,因此存在多种可能的转换方式


如果您不想用nul终止字符串,那么您应该使用其他人的答案中显示的FillChar+Move组合。

了解将字符串类型值复制到字符类型值数组的快速方法。我建议使用如下小辅助函数:

procedure StrToCharArray( inputStr:String; var output; maxlen:Integer);
type
    ArrayChar = Array[0..1] of Char;
begin
  StrLCopy( PChar(@ArrayChar(output)[0]),PChar(inputStr),maxlen);
end;
每次调用时,传入要复制的最大长度。请记住,如果缓冲区长度为15,则应传入14作为maxlen,这样,如果要始终终止字符串,就可以为终止nul字符留出空间:

StrToCharArray( UserInputStr,  MyRecord.MyField,  14 );
此函数将确保复制到记录中的数据以null结尾,前提是这是您想要的。请记住,在固定长度的字符数组中,由您决定规则是什么。空终止?完全填充空格或空字符。。。。字符串和字符数组非常不同,因此存在多种可能的转换方式


如果您不想用nul终止字符串,那么您应该使用其他人的答案中显示的FillChar+Move组合。

显而易见的答案当然是。
不要使用字符的压缩数组

请改用字符串。
如果使用
ansistring
,则1个字符将始终占用1个字节。 如果您使用
短字符串
同上

Ansistring与
Pchar
兼容,Pchar是指向
压缩字符数组的指针

这样你就可以写作了

function inputbox(a,b,c: ansistring): pchar;
begin
  Result:= a+b+c;
end;

var s: ansistring;
begin
  s:= inputbox('a','b','c');
end;
一些建议
看起来您正在将代码从c转换为Delphi

字符的压缩数组
与旧的(1995)
shortstring
减去
shortstring
开头的长度字节完全相同

我能想到的使用压缩字符数组的唯一原因是当您在磁盘上读取数据时,您有不想更改的遗留代码

我将保留从磁盘读取和写入的遗留代码,然后将数据传输到
ansistring
中,从那里开始只使用
ansistring

这很简单,德尔福会为你做一切。
而且
ansistring
速度更快,可以自动创建和销毁,可以有任何长度(最多2GB),使用的内存也更少,因为相同的字符串只存储一次(wh