0

I have a do-while loop designed to get a number from user input in the console. I included error checking and many optional variables to make it versatile (i.e. min and max allowed values, an array of values that must contain the input, and a params variable for any specific not allowed input values).

After redesigning the loop to use some continue statements (based on design constraints), the error checking no longer seems to be working.

public static int GetNumber(int min = int.MinValue, int max = int.MaxValue, string prompt = "Number", int[] permittedNums = null, params int[] exceptions)
{
 string? numString;
 int num;
 do
 {
 Console.Write($"{prompt}: ");
 numString = Console.ReadLine();
 ClearConsoleLine();
 if (!int.TryParse(numString, out num)) { continue; }
 if (permittedNums != null && !permittedNums.Contains(num)) { continue; }
 } while (num < min || num > max || exceptions.Contains(num));
 return num;
}

I checked to make sure that my logic was correct to make sure that at least the continue statement was hit, and as far as I could tell it should have worked, but it was allowing the input to go through without running the loop again.

I already tried looking at other questions but I couldn't find an answer.

asked Dec 26, 2023 at 1:03
5
  • variable num contains 0, so when you enter non numeric string - it remains 0, which is within limits and not in exceptions, so loop ends Commented Dec 26, 2023 at 1:13
  • Does this answer your question? Why is my continue keyword in my do-while loop not working? Commented Dec 26, 2023 at 1:13
  • @Ilya see my comment below - shouldn't it restart the loop when it hits continue? Commented Dec 26, 2023 at 1:18
  • 2
    @moshesilver you don't understand how continue works, it does not restart loop, it skips rest of loop's body, but condition is still checked Commented Dec 26, 2023 at 1:19
  • @ Ilya so is there another way to achieve the same functionality as continue in a regular loop? Commented Dec 26, 2023 at 1:20

3 Answers 3

2

you didn't provide detailed inputs, but this condition, iirc, wants to loop until user enters a legal number:

while (num < min || num > max || exceptions.Contains(num));

Let's say a simple example case, all parameters default, empty collection for exceptions. Once prompt starts, user enters any non-nubmer text, and TryParse fails. Note that num would be 0 on fail. continue gets called. Loop checks condition. Because Int32.MinValue < 0 < Int32.MaxValue, no condition will be met and the loop ends, thus causing the illusion of loop not working properly. That's the catch of TryParses actually, you need to consider about the bool returned by it instead of using num to check.

I suggest you write down a list of different inputs first, and think what result each of these inputs should produce, then you'll come up with the logic more clearly.

Sign up to request clarification or add additional context in comments.

1 Comment

my problem occurs before reaching that part of the code. if I try inputting a string for example then the first continue should restart the loop. the problem is that it's not and it's accepting the string
2

continue jumps to the next iteration of the loop, but the condition is still checked. Therefore use a boolean value to see whether it makes sense to even est for the end-sign of the loop:

public static int GetNumber(int min = int.MinValue, int max = int.MaxValue, string prompt = "Number", int[] permittedNums = null, params int[] exceptions)
{
 string? numString;
 int num;
 bool ended;
 do
 {
 ended = false;
 Console.Write($"{prompt}: ");
 numString = Console.ReadLine();
 ClearConsoleLine();
 if (!int.TryParse(numString, out num)) { continue; }
 if (permittedNums != null && !permittedNums.Contains(num)) { continue; }
 ended = true;
 } while ((!ended) || (num < min || num > max || exceptions.Contains(num)));
 return num;
}
DevSolar
71.1k22 gold badges141 silver badges217 bronze badges
answered Dec 26, 2023 at 1:26

Comments

1

continue actually is simple goto, and in loops it works like this:

do {
 ...
 continue;
 ...
} while (condition)

is equivalent to:

do {
 ...
 goto LABEL;
 ...
 LABEL:
} while (condition)

so, even after continue condition is still evaluated (or in case of for loop - counter is increased and so on).

you have multiple options, for example you can put all your continuation conditions in while's condition (it works because of short circuit evaluation):

do
{
 Console.Write($"{prompt}: ");
 numString = Console.ReadLine();
} while (
 !int.TryParse(numString, out num) ||
 (permittedNums != null && !permittedNums.Contains(num)) ||
 num < min ||
 num > max ||
 exceptions.Contains(num)
 );
return num;

but it is hard to read and modify, I'd prefer to see something like this:

while (true)
{
 Console.Write($"{prompt}: ");
 var numString = Console.ReadLine();
 int num;
 if (!int.TryParse(numString, out num)) { continue; }
 if (permittedNums != null && !permittedNums.Contains(num)) { continue; }
 if (num < min || num > max || exceptions.Contains(num)) { continue; }
 return num;
}

so, every time you have failed check - you skip return and start loop from the beginning

answered Dec 26, 2023 at 1:30

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.