在delphi 7中将整数转换为十六进制数

时间:2015-06-18 18:16:47

标签: delphi delphi-7

编写一个程序,将整数转换为十六进制表示,而不使用内置函数。

这是我的代码,但它不起作用。谁能说出错误在哪里?

发出错误:

  

“项目引发异常类EAccessViolation,消息'模块'Project.exe'中的地址00453B7B处的访问冲突。地址FFFFFFFF'。写入停止。使用步骤或运行继续。”

unit Unit1;

interface

uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics,     Controls,Forms,
  Dialogs;

type
  TForm1 = class(TForm)
  end;
function hexvalue(num:Integer):Char;

var
  Form1: TForm1;

implementation

{$R *.dfm}
function hexvalue(num:Integer):Char;
  begin
    case num of
      10: Result:='A';
      11: Result:='B';
      12: Result:='C';
      13: Result:='D';
      14: Result:='E';
      15: Result:='F';
    else Result:=Chr(num);
  end;
end;

var
  intnumber,hexnumber,actualhex:String;
  integernum:Integer;
  i,j,k:Byte;

begin
  InputQuery ('Integer Number','Enter the integer number', intnumber);
  integernum:=StrToInt(intnumber);
  i:=0;
  while integernum >= 16 do
    begin
      hexnumber[i]:=hexvalue(integernum mod 16);
      integernum:= integernum div 16;
      Inc(i);
    end;
  hexnumber[i]:= hexvalue(integernum);
  k:=i;
  for j:=0 to k do
     begin
      actualhex[j]:= hexnumber[i];
      Dec(i);
    end;
  ShowMessage(actualhex);

end.

2 个答案:

答案 0 :(得分:3)

第一个错误:String是1索引的。意味着它们的第一个字符的索引是1而不是0.您将“i”初始化为0然后尝试设置hexnumber [i]。

第二个错误:字符串可能是动态的,但它们不会自动增长。如果您尝试访问空字符串的第一个字符,它将无法工作。您需要调用SetLength(HeXNumber, NumberOfDigits )。您可以通过这种方式计算位数:

NumberOfDigits := Trunc(Log16(integernum)) + 1;

由于Log16实际上不存在,您可以使用LogN(16,integernum)或(Log(IntegerNum)/ Log(16)),具体取决于您的Delphi版本中的可用内容。

请注意,由于舍入错误,这可能会为非常非常大的值(高INT64范围)返回无效值。

如果您不想走这条路,可以用

替换指令
hexnumber := hexvalue(integernum mod 16) + hexnumber;

这也可以消除最后反转字符串的需要。

第三个错误:对循环变量使用无符号整数。虽然这是有争议的,但指令

for I := 0 to Count - 1 do

是Delphi中不常检查Count > 0的常见做法。当count = 0并使用无符号循环计数器时,您将获得整数溢出(如果您在项目选项中激活它们)或者您将循环高(I)次,这不是您想要的做。

第四个错误:已经提到:Result:=Chr(num)应该被Result := InttoStr(Num)[1]之类的东西取代。 就个人而言,我将使用数组实现该功能。

HexArr : Array[0..15] of char = ('0', '1',...,'D','E','F');
begin
  if InRange(Num, 0, 15) then
    Result := HexArr[Num]
  else
    //whatever you want
end;

答案 1 :(得分:3)

由于这显然是一项家庭作业,我不想为你破坏它并编写解决方案,而是试图引导你找到解决方案。

用户输入
在实际代码中,您需要为来自用户的任何错误做好准备,并检查输入是否仅为整数,并礼貌地要求用户在错误时更正输入。

转换循环
您可以使用mod 16integernumdiv 16的每个半字节移动到下一个半字节,从单位向更高阶的值。

将半字节转换为十六进制字符
你错了。如果您还要写出0..9的案例,那么您可以正确地使用case语句。正如其他人所评论的那样,Chr()采用ASCII码。但是,使用case语句进行这种简单的转换是一件非常繁琐的写法,而且效率不高 如果你有一个查找表(数组),索引(0..15)直接给你相应的十六进制字符,该怎么办?这会简单得多。像

这样的东西
const
  HexChars: array[_.._] of Char = ('0',_____'F')

我留给你填写缺失的部分。

形成结果(十六进制字符串)
您的第二个主要错误和AV的原因是您在尝试访问字符位置之前未设置字符串hexnumber的长度。另一个设计缺陷是向后填充hexnumber。因此,您需要一个额外的循环,您可以将订单转换为正确的顺序 至少有两种解决方案可以解决这两个问题:

  1. 由于您采用32位integer类型输入,因此十六进制表示不超过8个字符。因此,您可以将字符串的长度预设为8,并使用8 - i作为索引从低位置填充。作为最后一步,您可以根据需要修剪弦乐。
  2. 不要预设长度,只需在循环hexnumber := HexChars[integernum mod 16] + hexnumber;中进行连接。
  3. 负值
    您没有以任何方式考虑代码中负值的可能性,因此我认为它不是任务的一部分。