EPKasper
EPKasper

Reputation: 47

Ada loop stops after first input

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

Answers (1)

ajb
ajb

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

Related Questions