由于对数据性质的不确定性,我们开始向Chars读取一些bcd值。 例如,如果文件中的数据长度为6个字节,那么我们就像这样读取它:
var
fifi : TextFile;
path, res: AnsiString;
i : Integer;
tmp : AnsiChar;
begin
assignFile(fifi, path);
reset(fifi);
for i := 1 to 6 do
begin
read(fifi, tmp);
res := res + tmp;
end;
end.
因为二进制数据在每个字符上进行转换会使我们返回数据。
这是现在很难改变的事情。
我现在有一个自定义函数,它以字节数组的形式从字符串构造带符号的压缩bcd值。
然后我想在AnsiChar中执行与此数组的每个字节相反的操作,以便我们可以将它与过程中先前生成的ebcdic数据合并。
但是阅读功能自然而然地很难再现。总是有一些腐败或隐式转换正在我所建立的内容中完成。
以下是我的尝试:
function memoryStreamToString(str: TMemoryStream): AnsiString;
begin
setString(result, PChar(str.memory), str.size div sizeOf(AnsiChar));
end;
function byteToStr(t: array of Byte): AnsiString;
const
digits: array[0..15] of AnsiChar =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
var
i: Integer;
begin
result := '';
for i := low(t) to high(t) do
result := result + digits[(t[i] shr 4) and $0F] + digits[t[i] and $0F];
end;
var
buff : array of Byte;
bcdlen : Integer;
res : AnsiString;
//str : TMemoryStream;
begin
//code that init res, buff
// way number one
//str := TMemoryStream.Create;
//str.writeBuffer(buff[0], bcdLen);
//res := memoryStreamToString(str);
//str.free;
//way number two
//res := byteToStr(buff);
// way number three
//setLength(res, bcdLen);
//move(buff[0], res[1], bcdLen);
end.
所以我想的问题是如何在没有损坏的情况下在AnsiChar中填充一个字节? 我认为这样做不是好的做法,因为数据的性质没有得到尊重,但我们在实施阶段来不及改变它。
谢谢。
答案 0 :(得分:2)
除非您执行字符串转换操作,否则不会有任何损坏。将一个字节放入AnsiString
,如下所示:
str[i] := Chr(b); // I am assuming you are on a pre-Unicode Delphi
或者你可以使用演员:
str[i] := AnsiChar(b);
将单个字节放入预先分配的AnsiString
的元素中。在相反的方向你写:
b := ord(str[i]);
如果要将字节数组blit到字符串上,请使用:
SetLength(str, count);
Move(buff, Pointer(str)^, count);
此代码与第三种方法相同。它工作得很好,除非你对字符串执行一些后续操作,否则不会有损坏。你的第一种方法也会起作用,但过于复杂。你的第二种方法完全不同,涉及十六进制表示。我不太确定你想要在那里实现什么。
但你真的想要使用字节数组而不是字符串。一个动态的字节数组array of Byte
就是你的家伙。