Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 发送字符数组中的†字符而不是空格字符_Arrays_Delphi_Char_Pascal_Delphi 10 Seattle - Fatal编程技术网

Arrays 发送字符数组中的†字符而不是空格字符

Arrays 发送字符数组中的†字符而不是空格字符,arrays,delphi,char,pascal,delphi-10-seattle,Arrays,Delphi,Char,Pascal,Delphi 10 Seattle,我已将我的项目从XE5迁移到西雅图10。我仍在使用ANSII代码与设备通信。在我的新版本中,西雅图IDE发送的是†字符,而不是字符数组中Ansii代码中32的空格字符。我需要将空格字符数据发送到文本文件,但我不能 我试过32,就像我以前用过的一样,032和127,但都不起作用。有什么想法吗 以下是我如何使用: fillChar(X,50,#32); 方法签名var-X;计数:整数;Value:Ordinal如果要使用ANSI与设备通信,可以将数组定义为 x: array[1..50] of A

我已将我的项目从XE5迁移到西雅图10。我仍在使用ANSII代码与设备通信。在我的新版本中,西雅图IDE发送的是†字符,而不是字符数组中Ansii代码中32的空格字符。我需要将空格字符数据发送到文本文件,但我不能

我试过32,就像我以前用过的一样,032和127,但都不起作用。有什么想法吗

以下是我如何使用:

fillChar(X,50,#32);

方法签名var-X;计数:整数;Value:Ordinal

如果要使用ANSI与设备通信,可以将数组定义为

x: array[1..50] of AnsiChar;
在本例中,使用您使用的空格字符填充它

FillChar(x, 50, #32);
在Unicode环境中,使用AnsiChar数组作为通信缓冲区可能会很麻烦,因此我建议使用字节数组作为通信缓冲区

x: array[1..50] of byte;
并将其初始化为

FillChar(x, 50, 32);
尽管名称不同,FillChar填充的是字节,而不是字符

Char是Delphi 2009+中WideChar 2字节的别名,在以前的版本中,它是AnsiChar 1字节的别名

因此,如果您有一个由WideChar元素组成的50个元素的数组,那么该数组的大小是100字节。当您调用fillCharX,50,32时,它将填充前50个字节,每个字节的值为$20。因此,前25个WideChar元素的值为$2020,又称Unicode codepoint U+2020 DAGGER,†,而后25个元素的值没有任何意义

该问题在以下章节中进行了解释:

用指定值填充连续字节

在Delphi中,FillChar使用value value指定的值填充X引用的Count连续字节,value可以是Byte或AnsiChar类型

请注意,如果X是一个UnicodeString,这可能不会像预期的那样工作,因为FillChar需要一个字节计数,它与字符计数不同

此外,填充字符是单字节字符。因此,当Buf是一个单链分解时,代码FillCharBuf,LengthBuf,9;用代码点$0909而不是$09填充Buf。在这种情况下,应该使用StringOfChar例程

Embarcadero的白皮书中也解释了这一点,例如Cary Jensen的第28页:

实际上,这类代码的复杂性与指针和缓冲区本身无关。问题是由于字符被用作指针。因此,现在字符串和字符的大小(以字节为单位)发生了变化,这段代码所包含的一个基本假设不再有效:单个字符的长度为一个字节

由于这种类型的代码在Unicode转换和维护方面存在很大的问题,需要进行详细的检查,因此可以在可能的情况下对这种代码进行重构。简而言之,从这些操作中删除Char类型,然后切换到另一种更合适的数据类型。例如,Olaf Monien写道,我不建议对字符或字符串类型使用面向字节的操作。如果需要字节缓冲区,则使用“byte”作为byte;的[数据类型:buffer:array[0..255]

例如,过去您可能做过类似的事情:

var
  Buffer: array[0..255] of AnsiChar;
begin
  FillChar(Buffer, Length(Buffer), 0);
如果您只想转换为Unicode,可以进行以下更改:

var
  Buffer: array[0..255] of Char;
begin
  FillChar(Buffer, Length(buffer) * SizeOf(Char), 0);
另一方面,可以提出一个很好的理由,放弃使用Char数组作为缓冲区,并切换到Byte数组,正如Olaf所建议的那样。由于缓冲区的大小,这可能与第一段类似,但与第二段不同:

var
  Buffer: array[0..255] of Byte;
begin
  FillChar(Buffer, Length(buffer), 0);
更好的方法是,使用第二个参数FillChar,无论数组的数据类型如何,它都可以工作:

var
  Buffer: array[0..255] of Byte;
begin
  FillChar(Buffer, Length(buffer) * SizeOf(Buffer[0]), 0);
最后两个示例的优点是,您首先拥有了真正想要的东西,一个可以保存字节大小值的缓冲区。Delphi不会尝试应用任何形式的隐式字符串转换,因为它使用的是字节而不是代码单位。如果你想做指针数学,你可以用PByte。PByte是指向字节的指针

当您与需要指向字符或字符数组的指针的外部库交互时,可能无法进行类似的更改。在这些情况下,它们实际上是在请求一个字符缓冲区,而这些通常是AnsiChar类型


因此,为了解决您的问题,因为您正在与需要Ansi数据的外部设备交互,所以需要将数组声明为使用AnsiChar或Byte元素,而不是WideChar元素。然后您原来的FillChar调用将再次正常工作。

什么类型的“X”?西雅图不是“发送”,你的代码是。什么代码?X:Char的数组[1..50];所以你用$2020个字符填充数组的一半。在XE5中也是如此。你知道字符在两个版本中都是Unicode吗?@MBo是的,我在旧版本中使用过。XE5、Turbo Delphi等等。@TomBrunberg我要试试这个解决方案。问题几乎是一样的。谢谢@RudyVelthuis纠正我的打字错误,否则我想你会复制粘贴的, 正当因为你有两次同样的打字错误。