我是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;