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

String '';不是有效的标识符(Delphi XE5),string,delphi,delphi-xe5,String,Delphi,Delphi Xe5,我是DelphiXe5(Embarcadero的RAD Studio的一部分)的新手,在一个VCL表单项目中使用StrToFloat函数,该项目旨在构建一个简单的计算器 向用户显示文本的代码工作得很好,但我在提取文本时遇到了问题,无法让计算器实际执行计算。我确定的方法是在Tedit中向用户显示代码,并将要执行的代码存储在Tmemo中。按计算器上的按钮将数字存储到两者,然后按一个运算符(加法、减法、指数、乘法和除法的符号)在备忘录中开始一个新行。这样,每个数字都在自己的行上,每个运算符都在自己的行

我是DelphiXe5(Embarcadero的RAD Studio的一部分)的新手,在一个VCL表单项目中使用StrToFloat函数,该项目旨在构建一个简单的计算器

向用户显示文本的代码工作得很好,但我在提取文本时遇到了问题,无法让计算器实际执行计算。我确定的方法是在Tedit中向用户显示代码,并将要执行的代码存储在Tmemo中。按计算器上的按钮将数字存储到两者,然后按一个运算符(加法、减法、指数、乘法和除法的符号)在备忘录中开始一个新行。这样,每个数字都在自己的行上,每个运算符都在自己的行上

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

3
^
4
…在TMemo中

我想在行索引1处找到“^”符号(行从索引0开始,对吗?),并通过逻辑将
3
存储在
base
变量中,如果
^
行[1]
,那么
3
行[1-1]
,或者
行[0]
,并将
4
存储在
指数
变量中。这两个变量都属于扩展类型。这是我为实现这一点而创建的代码

 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;
当我运行计算器时,数字显示正确,但是当我点击equals按钮运行上面的代码时,我得到消息Project calculator\u.exe引发的异常类EConvertError,消息为“”,它不是有效的浮点值。

我知道StrToFloat函数试图转换空字符或其他(),但是我应该怎么做才能纠正这个问题呢

下面是每个按钮的代码——数字(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;
我可以根据要求发布完整的单位文件。

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

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]);
text返回的是整个文本,而不是您想要的。而是使用一些局部变量来保存查找值……这样,您可以设置断点并查看错误,然后使用以下方法查找“^”


请注意,此代码仅处理备忘录中的一个“^”(您的代码也有相同的问题),除此之外,还可以使用循环和状态引擎或其他解析逻辑来处理计算。

使用
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;
var
数量:柏油虫;
//其他变量在这里
开始
// ...
数字:=memCurrentEntry.Lines.Text.Split(“^”);
如果长度(数字)=2,则
尝试
基数:=StrToFloat(数字[0]);
指数:=StrToFloat(数字[1]);
结果:=幂(基数、指数);
除了
关于EConvertError do
开始
ShowMessage(格式('无法计算公式%s',[memCurrentEntry.Lines.Text]);
结果:=0;//回退到默认值,例如0
结束;
结束;
// ...
结束;

请更正问题标题。Q与“”没有任何关系“”不是有效的标识首先,欢迎来到Delphi社区!这里有很多信息,这无助于识别问题。这段代码的一个问题是它假设a^总是有一个前面的数字,因此David关于使用TryStrToFloat的回答将解决这个特定问题。有什么建议吗?我想一次执行多个计算,有点像内置的Microsoft计算器,或大多数科学计算器。一旦我让这个用于插入符号,我将把它应用到其他操作数/运算符/任何东西上。我理解你建议的要点,但不理解实施它的细节。最简单的方法是使用堆栈。推送和弹出堆栈的概念非常有效。把它想象成输入数字,按操作符将数字推到堆栈上并保存操作符。如果运算符为“=”,则查看该运算符并弹出变量,返回结果。因此2+2=将弹出两个条目(堆栈现在为空),执行加法并在堆栈上按4。然后输入*2将弹出堆栈中的2和4,将它们相乘,并在堆栈中放置8。。。清除当然会清除堆栈。OT:@skamradt,你可以要求版主将你的个人资料与旧的合并。好的。这有什么好处?TryStrToFloat在遇到异常时仍将执行吗?如何在Pascal/Delphi中处理异常?(我只做了几个星期)。请不要让我们在这里教你一门语言。请坚持具体问题。如果您想知道TryStrToFloat的功能,请按照答案中文档的链接进行操作。我希望你已经这么做了。是吗?我不知道这是个链接。我不是要你教我语言,我只是想理解你的答案。“我如何处理Pascal/Delphi中的异常?”是一个大问题。在评论中这样问是不公平的。
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;