''不是有效的标识符(Delphi XE5)

时间:2014-03-12 15:42:38

标签: string delphi delphi-xe5

我是Delphi XE5(Embarcadero的RAD Studio的一部分)的新手,并且在VCL Forms项目中使用StrToFloat函数来构建一个简单的计算器。

向用户显示文本的代码运行良好,但我无法以允许计算器实际执行计算的方式提取它。我已经确定的方法是在Tedit中向用户显示代码,并将要执行的代码存储在Tmemo中。按下计算器上的按钮可将数字存储到两者,按操作符(加,减,指数,乘和除的符号)会在备忘录中开始一个新行。这样,每个数字都在它自己的行上,每个运算符都在它自己的行上。

然后,我想通过迭代备忘录的行来提取与运算符相关的数字。对于3 ^ 4,您会看到......

3
^
4

...在TMemo中。

我想找到行索引1处的^符号(行从索引0开始,对吗?),并通过 3存储在base变量中>如果^lines[1],则3lines[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引发异常类EConvertError消息'''不是有效浮点值'。

我知道StrToFloat函数正在尝试转换空字符或其他内容(How do I identify what code is generating " '' is not a valid floating point value" error dialogue box),但我该怎么做才能纠正这个问题?

下面是每个按钮的代码 - 数字(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;

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

3 个答案:

答案 0 :(得分:3)

使用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,则会产生更清晰的代码。

答案 1 :(得分:0)

备忘录中行的使用是错误的:

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

lines.text返回整个文本,这不是你想要的。而是使用一些LOCAL变量来保存您的查找值...这样您就可以设置断点并查看错误,并使用以下方法找到“^”

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;

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

答案 2 :(得分:0)

使用StrToFloat没错。如果转换失败,用户应该看到错误消息。如果你想静静地抑制错误,那么你应该添加一个try / except来保护你的代码。

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;