Delphi - 设置字符串和 PAnsiChar 以及其他字符串不显示的问题
题
我正在得到 罗布·肯尼迪的建议 他的建议之一是使用 SetString
然后将其加载到显示它的VCL组件中。
我正在使用 Delphi 2009,所以现在 PChar 是 Unicode,
SetString(OutputString, PChar(Output), OutputLength.Value);
edtString.Text := edtString.Text + OutputString;
有效,我自己将其更改为 PChar,但由于移动的数据并不总是 Unicode,事实上它通常是 ShortString 数据......那么他实际上给我使用的是什么:
SetString(OutputString, PAnsiChar(Output), OutputLength.Value);
edtString.Text := edtString.Text + OutputString;
没有显示任何内容,但我检查了调试器,并且通常以我过去一次构建 1 个字符的方式出现的文本位于变量中。
奇怪的是,这不是我今晚第一次遇到这种情况。因为我试图想出另一种方法,所以我采纳了他的建议,我没有将其构建到 VCL 的 TCaption 中,而是将其构建到字符串变量中,然后复制它,但是当我发送它时,什么也没有显示。再次在调试器中构建数据的变量......有数据。
for I := 0 to OutputLength.Value - 1 do
begin
OutputString := OutputString + Char(OutputData^[I]);
end;
edtString.Text := OutputString;
上面的方法不起作用,但旧的缓慢的方法工作得很好......
for I := 0 to OutputLength.Value - 1 do
begin
edtString.Text := edtString.Text + Char(OutputData^[I]);
end;
我尝试将变量设置为 ShortString、String 和 TCaption,但没有显示任何内容。我还发现有趣的是,当我将同一数组中的十六进制数据构建到 RichEdit 中时,速度非常快,而在文本数据的编辑中进行则非常非常慢。这就是为什么我没有费心尝试更改 richedit 的代码,因为它运行得超快。
编辑添加 - 我想我找到了问题,但我没有解决方案。如果我编辑调试器中的值以删除无法显示的任何内容(通过旧方法用于不显示......没有失败)然后显示我剩下的内容。因此,如果这只是摆脱变成垃圾字符的字节的问题,我该如何解决这个问题?
我基本上从 SCSI 设备传入原始数据,并以十六进制编辑器的方式显示。我最初一次添加一个字符的缓慢方式成功地显示了字符串和其中不包含 Unicode 特定字符的 Unicode 字符串。更快的方法即使工作也不会以一种方式显示 ShortStrings,而另一种方式不会显示不使用非 0-255 字符的 UnicodeStrings。我真的很喜欢并且可以使用速度提升,但如果这意味着牺牲读取字符串的能力......那么这个应用程序有什么意义呢?
编辑3 - 好吧,现在我已经发现 0-31 是控制字符,32 及以上是有效的,我想我将尝试过滤字符并用 .这是我稍后计划模仿十六进制编辑器风格的事情。
如果有任何其他建议,我很高兴听到它们,但除此之外,我认为我可以制定一个比原来更快的解决方案,同时满足我的需要。
解决方案
我用PAnsiChar
在我的例子是有原因的。它看起来像以字节为单位,而不是以字符为被测量OutputLength
,所以我做了一定要使用一个类型,其长度总是以字节为单位。您还会注意到,我发现OutputString
的声明作为AnsiString
。
由于存储的Unicode编辑控件,虽然,将会有AnsiString
和UnicodeString
之间的转换。这将需要系统当前的代码页进去,但是这可能不是你想要的。你可能想声明变量为RawByteString
代替。这将不具有与它相关联的任何代码的页面,所以不会有任何意外的转换。
不要使用字符串,用于存储二进制数据。如果你正在构建一个相当于一个十六进制编辑器,那么你处理二进制数据。重要的是要记住这一点很重要。即使你的二进制数据的发生应用于包含较多,可以被解释为文本的字节,你不能把数据作为文本或者你会碰到正是你所看到的问题 - 字符如预期不会出现。如果您从SCSI设备得到一堆字节,然后将它们存储在字节,而不是字符数组。
在十六进制编辑器,你会发现,他们总是显示字节的十六进制值。它们可能会显示解释为字符的字节,但这是次要的,他们一般只表明可以代表ASCII字符的字节;他们没有试图获得与基本陈列太花哨。在好十六进制编辑器将提供给显示解释为宽字符数据,也。这有助于调试,因为用户可以关注一下以多种方式相同的数据。但他们只是的的意见的数据。他们没有真正改变数据的二进制内容。
其他提示
一些评论:
- 你的问题很不清楚。你到底想做什么?
- 您的问题读起来很糟糕,请使用拼写检查器检查您的文字。
- 您提到的问题是这样的: Delphi 从由非类型化指针填充的动态数组访问数据
- 请提供您的函数的完整代码示例,就像您在上一个问题中所做的那样,我想知道您是否实现了罗布·肯尼迪的建议或您在以下答案中给出的代码(希望没有:))
- 据我了解你的问题:您向 SCSI 设备发送一个查询,并获得一个字节数组,并将其存储在变量 OutputData 中。之后,您想要向用户显示您的数据。所以你真正的问题是: 如何向用户显示字节数组?
- 以同一用户身份登录,不要为每个新问题创建一个帐户。这样我们就可以跟踪您的问题历史记录并了解您所说的“获取建议”的含义。
如果我对你问题的真正含义是正确的,一些假设和建议:
- 将数据显示为十六进制字符串不会出现任何问题
- 在普通的 Memo 字段中显示数据会给您带来问题,尽管 Delphi 字符串可以包含任何字符(包括 0 字节),但显示它们会给您带来问题。例如,TMemo 将显示您的数据直到第一个 0 字节。您要做的(并且您自己给出了答案)是用虚拟字符替换不可见的字符。之后,您可以在 TMemo 中显示您的数据。实际上所有十六进制查看器都这样做,无法打印的字符将显示为点。
当你过滤掉非可视字符...你可能需要决定如何处理像9号(标签),#10(LF),#11(Verticle标签),#12他们夫妇做(FF-或新页),#13(CR)