Reputation: 47
Hi I am currently writing a program that reads inputs from a file and determines whether or not the number is neither prime nor composite, is composite, or prime. Basically my problem is that I can not get my program to continue it stops after one input, even though I have more numbers in my file that need to be evaluated. Here is my code:
WITH Ada.Text_IO, Ada.Integer_Text_IO;
USE Ada.Text_IO, Ada.Integer_Text_IO;
PROCEDURE TestPrime IS
PACKAGE Boolean_Io IS NEW Ada.Text_Io.Enumeration_Io(Boolean);
USE Boolean_Io;
N : Integer;
X : Natural := 2;
S : Integer;
IsPrime : Boolean := True;
C : Character;
BEGIN
WHILE NOT End_Of_File LOOP
Excep:
BEGIN
Get(N);
IF N = 0 OR N = 1 THEN
Put_Line(N'Img & " is neither prime nor composite");
END IF;
LOOP
S := N mod X;
IF S = 0 THEN
IsPrime := False;
END IF;
EXIT WHEN X = N - 1;
X := X + 1;
END LOOP;
IF IsPrime = True THEN
Put_Line(N'Img & " is prime");
ELSE
Put_Line(N'Img & " is composite");
END IF;
EXCEPTION
WHEN Data_Error =>
Put_Line("Data error: You must enter a number!!");
Get(C);
END Excep;
END LOOP;
END TestPrime;
I am just asking where my program is getting stuck and why it is happening. Any help will be greatly appreciated. Thank you!
Upvotes: 0
Views: 303
Reputation: 31699
Since you haven't described the exact symptoms (yet), I'm not sure whether this is the entire source of the problem or not. However, the declaration
X : Natural := 2;
will initialize X
at the beginning of the procedure only. It does not reinitialize X
every time it goes through the loop, because the declaration isn't inside the loop. Therefore, after the program processes the first number N
, X
will be N-1
when you're done. Since you don't reinitialize it, X
will have that same value. Then if the second number in your file is smaller than the first one, X
will start at a number larger than this; since you keep incrementing it by 1 and only exit the loop when it becomes equal to [the new N] - 1
, this will be a loooooooooooooooooooooooooong wait.
You can just say X := 2
at the beginning of your outer loop to reinitialize it. Another possibility is to declare X
as local inside the loop, instead of local to the whole procedure; something like
WHILE NOT End_Of_File LOOP
Excep:
DECLARE
X : Natural := 2;
BEGIN
and so on.
Keith's comments are worth following. A couple other things: as a matter of practice, I would always write something like exit when X >= N - 1;
instead of exit when X = N - 1;
. It shouldn't make a difference if you do things correctly, but this kind of thing can prevent hanging when something accidentally goes wrong. Finally, look at your program and see what happens if 0 or 1 is in the input. You print a message, but then you still go into the rest of your loop, which means that even if you reinitialize X
correctly, you will still start X
at 2 and then keep increasing it until it equals -1 or 0, which will never happen. (Actually, it will, due to wraparound, but it will take a long time.) Also, double-check your logic when N
is 2. You will either get the wrong answer or the program will hang. OK, one other thing: in your inner loop, when you set IsPrime := false;
, you still go through the rest of your loop, which is a waste of time. Try instead
IF S = 0 THEN
IsPrime := False;
exit; -- No need to keep looping!
END IF;
Upvotes: 1