【问题标题】:Converting Integer number into hexadecimal number in delphi 7在delphi 7中将整数转换为十六进制数
【发布时间】:2015-06-19 13:50:46
【问题描述】:

编写一个程序,在不使用内置函数的情况下将整数转换为其十六进制表示。

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

报错:

“项目引发异常类 EAccessViolation,并带有消息“模块 'Project.exe' 中地址 00453B7B 的访问冲突。写入地址 FFFFFFFF'。进程已停止。使用 Step 或 Run 继续。”

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.

【问题讨论】:

  • Result:=Chr(num); 高度可疑。例如,Chr(3)等于'3'。看看en.wikipedia.org/wiki/ASCII
  • Chr($ffffffff)? ......
  • Too many errors... 1) 你没有为hexnumber设置长度,所以你不能通过索引字符(hexnumber[i])来访问它,因为那些字符索引没有'不存在。 2)Chr(num) 完全错误。 Chr(3) 不会按照你的想法去做。 3) 你的case 只能正确处理 10..15;如果num = 17、23、64 或 99 会发生什么? 4)你随意混合各种数据大小。 5) 参见#1,将所有hexnumber 实例替换为actualhex
  • @Ken White 您提到的错误 #3 永远不会发生,因为十六进制值函数的参数始终为 (mod 16)。
  • @Ansh43 我看不到问题中指定的内容。

标签: delphi delphi-7


【解决方案1】:

第一个错误:字符串是 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 并使用无符号循环计数器时,您将获得整数溢出(如果您在项目选项中激活了它们),或者您将循环 High(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;

【讨论】:

    【解决方案2】:

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

    用户输入
    在实际代码中,您需要为用户的任何错误做好准备,并检查输入是否真的只是整数,如果有错误,请礼貌地要求用户更正输入。

    转化循环
    你已经搞定了,使用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;

    负值
    您没有以任何方式考虑代码中存在负值的可能性,因此我认为这不是任务的一部分。

    【讨论】:

      猜你喜欢
      • 2010-10-16
      • 2014-04-16
      • 2016-12-04
      • 1970-01-01
      • 1970-01-01
      • 2012-03-08
      相关资源
      最近更新 更多