0 arrays delphi pascal char delphi-10-seattle
我已经将项目从XE5迁移到了西雅图10。我仍在使用ANSII代码与设备通信。在我的新构建中,Seattle IDE在Char数组中发送†字符而不是空格char(在Ansii代码中为#32)。我需要将空格字符数据发送到文本文件,但不能。
我尝试了#32(就像我以前使用过的一样),#032和#127,但是它不起作用。任何的想法?
这是我的用法:
fillChar(X,50,#32);
Run Code Online (Sandbox Code Playgroud)
方法签名(var X; count:Integer; Value:Ordinal)
尽管有名称,但FillChar()填充字节,而不是字符。
Char是WideCharDelphi 2009+中(2个字节)的别名,在以前的版本中,它是AnsiChar(1个字节)的别名。
因此,如果您有一个包含50个元素的元素数组WideChar,则该数组的大小为100个字节。当您调用时fillChar(X,50,#32),它将使用每个值填充前50 个字节$20。因此,前25个WideChar元素的值将为$2020(aka Unicode codepoint U+2020 DAGGER,†),而后25个元素将没有任何有意义的值。
在FillChar()文档中解释了此问题:
用指定的值填充连续的字节。
在Delphi中,FillChar用Value指定的值填充Count连续字节(由X引用)(值可以是Byte或AnsiChar类型)
请注意,如果X是UnicodeString,则这可能无法按预期方式工作,因为FillChar期望一个字节计数,该字节计数与字符计数不同。
另外,填充字符是单字节字符。因此,当Buf是UnicodeString时,代码为FillChar(Buf,Length(Buf),#9); 用代码点$ 0909而不是$ 09填充Buf。在这种情况下,应使用StringOfChar例程。
在Embarcadero的Unicode迁移资源白皮书中也对此进行了说明,例如在Cary Jensen 撰写的Delphi纯粹的Unicode迁移:第一线的故事和建议的第28页上:
实际上,这种类型的代码的复杂性本身与指针和缓冲区无关。问题是由于Chars被用作指针。因此,现在字符串和字符的大小(以字节为单位)已更改,此代码大部分包含的基本假设之一不再成立:单个字符的长度为一个字节。
由于这种类型的代码对于Unicode转换(以及通常的维护)而言是个问题,并且需要进行详细的检查,因此可以在可能的情况下为重构此代码提供一个很好的论据。简而言之,从这些操作中删除Char类型,然后切换到另一个更合适的数据类型。例如,Olaf Monien写道:“我不建议对Char(或String)类型使用面向字节的操作。如果需要字节缓冲区,则将'Byte'用作[the]数据类型:buffer:array [0 ..255]字节;”。
例如,过去您可能做过这样的事情:
Run Code Online (Sandbox Code Playgroud)var Buffer: array[0..255] of AnsiChar; begin FillChar(Buffer, Length(Buffer), 0);如果只想转换为Unicode,则可以进行以下更改:
Run Code Online (Sandbox Code Playgroud)var Buffer: array[0..255] of Char; begin FillChar(Buffer, Length(buffer) * SizeOf(Char), 0);另一方面,正如奥拉夫(Olaf)建议的那样,可以为放弃使用Char数组作为缓冲区,而切换到Byte数组而提出一个很好的论据。这可能看起来像这样(由于缓冲区的大小,它类似于第一段,但与第二段不同):
Run Code Online (Sandbox Code Playgroud)var Buffer: array[0..255] of Byte; begin FillChar(Buffer, Length(buffer), 0);更好的是,对FillChar使用第二个参数,无论数组的数据类型如何,该参数都可以工作:
Run Code Online (Sandbox Code Playgroud)var Buffer: array[0..255] of Byte; begin FillChar(Buffer, Length(buffer) * SizeOf(Buffer[0]), 0);最后两个示例的优势在于,您首先拥有了真正想要的东西,一个可以容纳字节大小值的缓冲区。(而且Delphi不会使用任何形式的隐式字符串转换,因为它使用字节而不是代码单元。)而且,如果要进行指针数学运算,则可以使用PByte。PByte是指向字节的指针。
可能无法进行类似更改的一个地方是当您与需要指向字符或字符数组的指针的外部库接口时。在这种情况下,他们实际上是在要求字符缓冲,而这些通常是AnsiChar类型。
因此,为了解决您的问题,由于您正在与需要Ansi数据的外部设备进行交互,因此需要将数组声明为using AnsiChar或Byteelements而不是(Wide)Charelement。然后,您的原始FillChar()呼叫将再次正常工作。
| 归档时间: |
|
| 查看次数: |
513 次 |
| 最近记录: |