数据类型验证

时间:2013-09-17 09:32:10

标签: freepascal

我刚开始使用Object Pascal进行计算机研究,所以对于你们这里的许多人来说这可能是一个简单的问题。我正在尝试为Sum和Average计算器构建一个验证系统,以便不能接受非整数的答案,但也不会使软件崩溃。我已经尝试了几个小时来获得这个解决方案,当它处于当前状态时,如果我输入一个整数,它会把它解释为非整数,而如果我输入一个非整数,程序就会崩溃。反正有吗?

编码目前看起来像这样:

Program SumAverageCalculator;

{$APPTYPE CONSOLE}

uses
  SysUtils;

Const
  NumberOfIntegers = 3;

Var
  NumberOne, NumberTwo, NumberThree: integer;
  Sum: integer;
  Average: real;

Begin
  Writeln ('=======================================');
  Write ('What is your first number? '); readln(NumberOne);
  If NumberOne-sqr(0) <> 1 then
    Begin
      Write ('Please write an integer only.  What is your first number? '); readln(NumberOne);
    End
  Else
    Begin
      Write ('Great, that is an Integer! ');
    End;
  Write ('And the second number? '); readln(NumberTwo);
  If NumberTwo-sqr(0) <> 1 then
    Begin
      Write ('Please write an integer only.  What is your second number? '); readln(NumberOne);
    End
  Else
    Begin
      Write ('Great, that is an Integer! ');
    End;
  Write ('And the third number? '); readln(NumberThree);
  If NumberThree-sqr(0) <> 1 then
  Begin
      Write ('Please write an integer only.  What is your third number? '); readln(NumberOne);
  End
  Else
    Begin
      Write ('Great, that is an Integer! ');
    End;
  Sum := NumberOne + NumberTwo + NumberThree;
  Average := Sum/NumberOfIntegers;
  Writeln;
  Writeln ('=======================================');
  Writeln ('The number of given integers was ', NumberOfIntegers);
  Writeln ('Your first number was ', NumberOne);
  Writeln ('Your second number was ', NumberTwo);
  Writeln ('Your third number was ', NumberThree);
  Writeln ('=======================================');
  Writeln ('The Sum of your numbers is ', Sum);
  Writeln ('The Average of your numbers is ', Average: 1:2);
  Writeln ('=======================================');
  Readln;
End.

感谢您提供任何帮助。 :)

1 个答案:

答案 0 :(得分:2)

这是因为你将整数变量传递给readln调用,它真的想在那里放一个整数。如果它不能(输入不是整数),它将崩溃。解决方案是首先以最一般的形式读取输入,即字符串,检查它是否为整数,然后将其转换为1。

当然,你不必自己做所有这些。 sysutils单元有一些有用的功能,其中包括TryStrToInt函数,它执行的操作:它会尝试将字符串输入转换为整数,并让您(开发人员)知道如果它失败而不是崩溃和燃烧。

uses
  SysUtils;

Var
  Input: String;
  IsInteger: Boolean;
  Value: Integer;
begin
  Write('Enter an integer: ');
  ReadLn(Input); // will work, user input can always be represented by a string

  IsInteger := TryStrToInt(Input, Value);

  if IsInteger then
  begin
    // Do stuff with "Value" which contains the input integer
  end
  else
  begin
    WriteLn('Sorry, that''s not an integer.');
  end;
end.

当然,如果您经常这样做,那么实现一个类似于readln的辅助函数可能是有意义的,但是检查本身并打印出错误而不会崩溃(可能是程序)可以继续询问整数,直到用户遵守,或者它应该优雅地终止)。例如,上面的一些代码可以包含在实用函数readint中。

一旦遇到异常,您将找到一种更通用的方法来处理程序中的故障并正确响应它们以避免程序因最轻微的用户错误而崩溃,但此时这可能就是您所看到的对


如果您想知道out函数在TryStrToInt函数中意味着什么,它与var类似,但它基本上意味着“我将填写此值,但我不会尝试阅读它((只写参数),不像var,这意味着“我将填写此值,但我可能会尝试在之前读取它”(读写参数) 。因此,out参数在使用之前不需要初始化(所以在某种程度上,out参数是“第二个返回值”,这在这种情况下是有意义的,因为TryStrToInt函数需要返回两件事:输入是否为整数,以及该整数是什么,但函数只能有一个“标准”返回值。)