user2786920
user2786920

Reputation: 13

Datatype Verification

I'm just starting out with Object Pascal for my computer studies so this is probably an easy question for many of you here. I'm trying to build a verification system for a Sum and Average Calculator so that answers which are not integers cannot be accepted but also don't crash the software. I've been trying for hours to get a solution for this and whilst it's in its current state, if I input an integer it would interpret it as a noninteger, whilst if I input a noninteger the program just crashes. Is there anyway around this?

The coding currently looks like this:

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.

Thank you for any help given. :)

Upvotes: 1

Views: 98

Answers (1)

Thomas
Thomas

Reputation: 3381

This is really because you passed an integer variable to the readln call, and it really wants to put an integer there. If it can't (the input is not an integer), it will crash. A solution is to first read the input in the most general form possible, that is, a string, check that it is an integer, and then convert it to one.

Of course, you don't have to do all that yourself. The sysutils unit has some helpful functions, and among them the TryStrToInt function, which does what it says: it will try to convert a string input to an integer, and will let you (the developer) know if it fails instead of crashing and burning.

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.

Of course, if you're going to be doing this often, it may make sense to implement a helper function that acts like readln but does the checking itself and prints out an error without crashing (perhaps the program could keep asking for the integer until the user complies, or perhaps it should gracefully terminate). For instance, some of the code above could be wrapped up in a utility function readint.

Once you come across exceptions, you'll find a more general way to handle failures in your program and respond to them properly to avoid your program crashing on the slightest user error, however at this point this is probably what you are looking for.


If you are wondering what the out thing means in the TryStrToInt function, it's similar to var, but it basically means "I am going to be filling out this value, but I won't try to read it" (a write-only parameter) unlike var which means "I am going to fill out this value, but I might try to read it before" (a read-write parameter). So an out parameter need not be initialized before being used (so in a way, an out parameter is a "second return value", which makes sense in this case since the TryStrToInt function needs to return two things: whether the input was an integer, and what that integer was, but functions can only have one "standard" return value).

Upvotes: 2

Related Questions