Reputation: 13
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
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