不是有效的标识符 (德尔福 XE5)



我是Delphi Xe5的新手(Embarcadero的Rad Studio的一部分),并在VCL表单项目中使用strtofloat函数,旨在构建一个简单的计算器。

将文本显示给用户的代码运行良好,但是我很难以一种允许计算器实际执行计算的方式提取它。我解决的手段是将代码显示给用户,并存储在TMEMO中执行的代码。按下计算器上的按钮将数字存储到两者中,然后按一个操作员(添加,减去,指数,乘和分隔的符号)在备忘录中启动了一条新线路。这样,每个数字都在自己的线上,每个操作员都在自己的行中。

然后,

我想通过迭代备忘录来提取相对于操作员的数字。对于3 ^ 4,您会看到...

3
^
4

...在tmemo。

我想在行索引1中找到 ^符号(线从索引0开始,对吗?),然后通过逻辑中的 base变量存储 3如果^是CC_4,则3,则是lines[1-1],或lines[0] ,然后将4存储在exponent变量中。这两个变量均为类型扩展。这是我创建的代码...

 procedure TForm1.btnEqualsClick(Sender: TObject);
var
  i: Integer;
  base: extended;
  exponent: extended;
  result: extended;
begin
  {This For loop looks for the exponentiation operator (^) in memCurrentEntry. If
   it's found, it then solves the equation.}
   for i := Low(memCurrentEntry.Lines.Text.Length) to High(memCurrentEntry.Lines.Text.Length) do
    if AnsiContainsStr(memCurrentEntry.Lines.Text, '^') then
    begin
        base := StrToFloat(memCurrentEntry.Lines[ansipos('^', memCurrentEntry.Lines.Text)-1]);
       exponent := StrToFloat(memCurrentEntry.Lines[ansiPos('^', memCurrentEntry.Lines.Text)+2]);
       result := power(base, exponent);
    end;

当我运行计算器时,数字会正确显示,但是当我点击"等价"按钮以运行上面的代码时,我会得到消息 project calculator_u.exe提出的exception class econverterror带有消息'''''不是一个有效的浮点值'。

我知道strtofloat函数正在尝试转换一个null字符或其他内容(我如何确定"代码"生成的"不是有效的浮点值"错误对话框",但是我应该做什么才能更正这个?

以下是每个按钮的代码 - 数字(0、1、2、3等)更改,但其余的都相同...

procedure TForm1.btn0Click(Sender: TObject);
begin
  //Adds the digit  0 to the end of the current number in memCurrentEntry
  memCurrentEntry.SelStart := Length(memCurrentEntry.Text);
  memCurrentEntry.Lines.Text := Copy(memCurrentEntry.Lines.Text,1,
    memCurrentEntry.SelStart)+'0'+ Copy(memCurrentEntry.Lines.Text,
    memCurrentEntry.SelStart+1,Length(memCurrentEntry.Lines.Text)
    - memCurrentEntry.SelStart);
  //Adds the digit  0 to the end of the current number in edtCurrentEntry
  edtcurrententry.Text := edtcurrententry.Text + '0';
end;

我可以根据要求发布完整的单元文件。

使用TryStrToFloat。这返回布尔值,指示转换是否成功。

var
  str: string;
  val: Double;
....
if TryStrToFloat(str, val) then
  // val contains the floating point value represented by str
else
  // str does not contain a floating point value, do something else with it

当然,您可以使用StrToFloat,并捕获异常。但是,由于您期望遇到例外,因此,如果您使用TryStrToFloat

备忘录上的线条使用是错误的:

base := StrToFloat(memCurrentEntry.Lines[ansipos('^', memCurrentEntry.Lines.Text)-1]);

line.Text返回整个文本,这不是您想要的。而是使用一些局部变量保持您的查找值...这样,您可以设置一个断点并查看错误并使用以下方法定位"^"

result := 0;
carrotLine := memCurrentEntry.Lines.IndexOf('^');
if carrotline > 0 then // must be 1 or greater, so a number can be at the 0 position
  begin
    base := TryStrToFloat(MemCurrentEntry.Lines[carrotLine-1],0);
    exponent := 0;
    // only try to read the next value if there is one.  
    if memCurrentEntry.Lines.Count >= carrotLine then
      exponent := TryStrToFloat(MemCurrentEntry.Lines[carrotline+1],0);
    result := power(base,exponent);
  end;

请注意,此代码仅处理备忘录中的单个 ^(您的代码有相同的问题),超越此范围就是使用循环,可能是状态引擎或其他一些解析逻辑来处理计算。

使用 StrToFloat并没有错。如果转换失败,则用户应看到错误消息。如果您想安静地抑制错误,则应添加尝试/除保护代码外。

try
  Value := StrToFloat(A_String);
except
  on EConvertError do
    Value := 0; // Fallback to a default value or execute other code logic
end;

根据您给定的代码示例,如果以您给定的格式输入基数和指数(第一行是基本,第二行是"^",第三行是指数)。我建议您写下您的代码如下:

var
  Numbers: TArray<string>;
  // Other variables go here
begin
  // ...
  Numbers := memCurrentEntry.Lines.Text.Split('^'); 
  if Length(Numbers) = 2 then
  try
    Base := StrToFloat(Numbers[0]);
    Exponent := StrToFloat(Numbers[1]);
    Result := Power(Base, Exponent);
  except
    on EConvertError do
    begin
      ShowMessage(Format('Unable to calculate the formula %s', [memCurrentEntry.Lines.Text]));
      Result := 0; // Fallback to a default value, such as 0
    end;
  end;
  // ...
end;

最新更新