Why does my while loop keep executing even when the value is true?

198 views Asked by At

I tried using the Do While loop originally but was having the same results as the while loop. The user must enter a number 28 - 31. Upon the first try if the user would enter the value correctly it would move on to the next part of the code. However, if the user enters an incorrect value it will ask for a number again but, no matter what they enter it keeps repeating.

#include <cs50.h>
#include <stdio.h>

 int main(void)
 {

     printf("Days in month: ");
     int daysInMonth = GetInt();    

     while (daysInMonth < 28 || daysInMonth > 31)
     {

         printf("Days in month: ");
         int daysInMonth = GetInt(); 

         printf("%i\n", daysInMonth);

     }

     printf("Pennies on the first day: ");
     int pennies = GetInt();

     while (pennies < 1)
     {

        printf("Pennies on the first day: ");
        int pennies = GetInt();

     }

}

The printf statement was for debugging purposes to test if daysInMonth is reassigning the value.

2

There are 2 answers

2
Kiril Kirov On BEST ANSWER

In the first while, you have:

 int daysInMonth = GetInt(); 

This defines a new variable daysInMonth, local for the while's body, which hides the outer variable with the same name. So, in the condition of the while loop, you use the outer daysInMonth, in the body, you use the inner daysInMonth.

I guess you want to remove the int part from this row and just modify the outer daysInMonth.

Actually, you have the same situation in the second while loop.

0
Sourav Ghosh On

TL:DR you have two different variables named daysInMonth in your code, with overlapping scope, which creates the problem.

You have the same problem with pennies variable, too.


To elaborate,

int daysInMonth = GetInt();

creates a (another) variable which is local to the while loop body. It shadows the outer daysInMonth variable, so in the conditional check, the value never changes. Change to

  daysInMonth = GetInt(); 

inside the while loop body.

Quoting c11, chapter ยง6.2.1, Scopes of identifiers

[...] If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the end of the associated block. [...]

and

[...] If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will end strictly before the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.