# Indefinite loops where the first time is different

This isn't a serious problem or anything someone has asked me to do, just a seemingly simple thing that I came up with as a mental exercise but has stumped me and which I feel that I should know the answer to already. There may be a duplicate but I didn't manage to find one.

Suppose that someone asked you to write a piece of code that asks the user to enter a number and, every time the number they entered is not zero, says "Error" and asks again. When they enter zero it stops.

In other words, the code keeps asking for a number and repeats until zero is entered. In each iteration except the first one it also prints "Error".

The simplest way I can think of to do that would be something like the folloing pseudocode:

``````int number = 0;
do
{
if(number != 0)
{
print("Error");
}
print("Enter number");
number = getInput();
}while(number != 0);
``````

While that does what it's supposed to, I personally don't like that there's repeating code (you test number != 0 twice) -something that should generally be avoided. One way to avoid this would be something like this:

``````int number = 0;
while(true)
{
print("Enter number");
number = getInput();
if(number == 0)
{
break;
}
else
{
print("Error");
}
}
``````

But what I don't like in this one is "while(true)", another thing to avoid.

The only other way I can think of includes one more thing to avoid: labels and `goto`s:

``````    int number = 0;
goto question;
error:
print("Error");
question:
print("Enter number");
number = getInput();
if(number != 0)
{
goto error;
}
``````

Another solution would be to have an extra variable to test whether you should say "Error" or not but this is wasted memory.

Is there a way to do this without doing something that's generally thought of as a bad practice (repeating code, a theoretically endless loop or the use of `goto`)?

I understand that something like this would never be complex enough that the first way would be a problem (you'd generally call a function to validate input) but I'm curious to know if there's a way I haven't thought of.

• Why is "while(true)" a thing to avoid? – A. I. Breveleri Jun 12 '14 at 10:20
• In this example it's not that important (because it's short) but in general, the best arguments against `while(true)` I've read are a)it makes it harder for a (human) reader to know what ends the loop and b)it makes it easier for future changes to remove the clause by mistake. – George T Jun 12 '14 at 15:21

The following solution avoids repetition and separates the concerns of getting the input and validating it:

``````do
{
print "Enter number"
number = getInput()
} while(!numberValid(number))

bool numberValid(number) {
if (number == 0) {
return true
} else {
print "Error!"
return false
}
}
``````
• One of the only uses I know of for putting the `while` at the end. – Robert Harvey Jun 10 '14 at 16:09

In Ruby I would consider this to be a guard clause and I would write it as either:

``````do_something if condition
``````

or

``````do_something unless condition
``````

I use these sparingly though. If there is a lot of code (more than 2 statements or lines say) I prefer the traditional `if then else` construct.

The main time I use is is for short conditions so that I can write the single line:

``````procA if x=1
``````

instead of the 3 lines:

``````if x=1 then
procA
end
``````

I'd separate the two behaviours The first is getting a number for the user, the second is validating it and eventually re-asking it So I'd go like this ``` int number = 0; print "Enter number"; number = getInput(); while(number != 0) { print "Error!"; number = getInput(); } ``` Maybe you could not like the double input line, but I think it's a nice trade off

• I'd say this has the same "problem" (for my personal tastes) as the original example. More so if you repeat the second "Enter number" line. :) – George T Jun 10 '14 at 7:34

You could do something like:

``````int number;
while((number = solicitNumber()) != 0) {
print("Error!");
}

...

int solicitNumber() {
print("Enter number");
return getInput();
}
``````