views:

359

answers:

7
    boolean r = false ; int s = 0 ;
    while (r == false) ; 
    {
        s = getInt() ; 
        if (!(s>=0 && s<=2)) System.out.println ("try again not a valid response") ; 
        else r = true ; 
    }

The text never displays itself even when a 3 or a 123 is entered and the loop never terminates. Whats wrong here?

+28  A: 

You have a semicolon after the condition. When you use braces to specify a block for your while you don't use a semicolon.

Daniel DiPaolo
indeed. that is the problem
David
Hehe... `while (r==false) /*DO NOTHING*/ ;`
Atømix
+6  A: 

Remove the ';' after while.

Alex
+6  A: 

Others have pointed out the bug, but your code is scary in other ways that will eventually trip you up:

if (!(s>=0 && s<=2)) System.out.println ("try again not a valid response") ; 
else r = true ; 

That's bad because you can easily intend more than one statement to run in the case of the if or else clause. Use curly braces and avoid placing conditional statements on a single line:

if (!(s>=0 && s<=2))
{
    System.out.println ("try again not a valid response");
}
else
{
    r = true;
}

It's easier to read and far less likely to introduce hard-to-see bugs.

Jonathon
I disagree on using curly braces. If it's a single statement, it's a single statement. As a matter of style, I will indent but not use curlies for single statements... however this is a religious battle.
Atømix
@Atomiton absolutely, I prefer to use them all the time because I'm likely to come back and change it at some point, which is when I'll screw up if I didn't put them there in the first place. At least put them on a different line -- I hope we can agree on that :)
Jonathon
I never use curly braces for a single statement, and I often come back and add more to it, and I have never accidentally forgotten to add braces and screwed up my control flow... Unless I have been writing python for awhile and then come back to C, that is.
Carson Myers
i never come back and make that mistake.
David
Although I often leave off the braces on a single-line, I can't defend the practice. The fact is, having the braces there costs virtually nothing, even if they somehow threw you off a little, it would be less than a second to glance at it again. On the other hand, leaving them off--say even once in a thousand "if" statements (let's say when you have been writing python for a while and then come back to C) if you happen to screw it up it could take minutes or hours to fix--that's indefensible and pretty clearly wrong. Yet still I leave them off more often than not...
Bill K
I love it when people say something like 'I never come back and make that mistake'. Because it may not be you who comes back to the code, and in any case, code written more than a couple of months ago may a well have been written by someone else.
Paul McKenzie
separate statements on their own line. it's obvious.
Paul McKenzie
+2  A: 

while(r == false)

should be

while(!r)

Despite what everyone else said about the semicolon, that is what I think is wrong with it :)

John V.
`while(r == false)` is more explicit and readable. I suppose people could also argue that is should be `while(false == r)`, but I hate that. Anyways, it isn't that he 'should' change it to `!r` because `r` is a boolean so it won't matter either way, meaning that it's just a matter of style.
Carson Myers
Consistently following the convention `r` and `!r` instead of `r == false` and `r == true` avoids the error of `r = false` and `r = true` (which will NOT cause a compile error in java). If you want to make it more explicit and readable, rename `r` to something like `continue` or `found`.
ILMTitan
continue is a keyword so that would make a terrible variable name. You are right, though, things like r and s are terrible variable names. Use a modern IDE with auto-completion and call it something sensible, like done or found.
ajs410
@Myers I disagree. I think r == false is code stink and would never want to see someone using it in the code I am working with.
John V.
+2  A: 

+1 to Daniel DiPaolo. I thought I'd post a separate answer to provide clarification of why this is the case.

While loops in Java can be written in one of two ways. If there is just one line to the body of the loop, you can write them in a short-hand fashion:

while (true)
    System.out.println("While loop");

This will print out "While loop" on the console until the program ends. The other option is to specify a loop body between braces, as you have done above:

int i = 0;
while (i < 10) {
    System.out.println("i = " + i);
    i++;
}

This will print out "i = 0", "i = 1", ..., "i = 9" each on a separate line.

What the code you posted does is confuse the two. In the short-hand while loop, the Java parser expects to find a statement between the while loop condition and the semi-colon. Because it does not find a statement here, the while loop runs, but does nothing; it has no body. Furthermore, because the loop has no body, there is no opportunity for your variable r to assume a new value; the condition always evaluates to true and the loop never exits.

If you were to negate the condition in the while loop in your example, i.e.,

boolean r = false ; int s = 0 ;
while (r != false) ; 
{
    s = getInt() ; 
    if (!(s>=0 && s<=2)) System.out.println ("try again not a valid response") ; 
    else r = true ; 
}

(note I left the erroneous semicolon in there), you would find that your intended loop body would execute precisely once, as the loop would never run.

alastairs
+2  A: 

In addition to other comments, you should also change the if to

if (s < 0 || s > 2)

It's much more understandable this way.

fish
+1 Absolutely, the negation makes it a chore to read something that should be simple.
Jonathon
A: 

Unrelated answer, I really really recommend you to follow Sun's style guidelines.

boolean r = false ; 
int s = 0 ;
while (r == false) {
    s = getInt() ; 
    if (!(s>=0 && s<=2)) {
        System.out.println ("try again not a valid response") ; 
    } else {
      r = true ;
    } 
}

You could get rid of the r variable and the if/else condition if you evaluate the result in the loop it self.

int s = 0;

while( ( s = getInt() ) < 0 || s > 2 ) {
    System.out.println( "Try again, not a valid response");
}
OscarRyz