While loop breaks unintentionally - c#

I am in my second week of C# training, so I am pretty new to programming. I have to make a program that returns the smallest integer out of a series of random integer inputs. Once the input = 0, the program should break out of the loop. I am only allowed to use while and for loops. For some reason my program breaks out of loop after the second input and it looks like it doesn't even care if there is a "0" or not. Could you please see where I went wrong? I have been busting my head off with this. Sorry if this question has already been posted by somebody else but I did not find an answer to it anywhere.
PS: The zero input should be taken into account for the comparison.
So this is what I've got so far:
class Program
{
static void Main()
{
int i = 0;
int input = Int32.Parse(Console.ReadLine());
int min = default;
while (input != 0)
{
Console.ReadLine();
if (i == 0)
{
min = input;
break;
}
if (input < min && i !=0)
{
input = Convert.ToInt32(Console.ReadLine());
min = input;
}
i++;
}
Console.WriteLine(min);
}

First of all you will want to re-read the documentation for for- and while-loops. There are several useful pages out there.. e.g. for / while.
Problem
The reason why your loop breaks is that you initialize i with 0.
int i = 0;
Inside your loop you are using the if-statment to break the loop if the condition "i is 0" is met.
if (i == 0)
{
min = input;
break;
}
The input that the user has to provide each iteration of the loop is ignored by your program as you are never storing this kind of information to any variable.
while (input != 0)
{
Console.ReadLine();
// ...
}
Possible Solution
As a beginner it is helpful to tackle tasks step by step. Try to write down each of this steps to define a simple algorithm. As there are many solutions to this problem one possible way could be:
Declare minimum value + assign max value to it
Use a while loop and loop till a specific condition is matched
Read user-input and try converting it to an integer
Check whether the value is 0 or not
4.1. If the value is 0, go to step 8
4.2. If the value is not 0, go to step 5
Check whether the value is smaller than the current minimum value
5.1. If the value is smaller, go to step 6
5.2. If the value is not smaller, go back to step 3
Set the new minimum
Go back to step 3
Break the loop
End program
A program that handles the above steps could look like:
using System;
namespace FindMinimum
{
public class Program
{
static void Main(string[] args)
{
// Declare minimum value + assign initial value
int minValue = int.MaxValue;
// Loop until something else breaks out
while (true)
{
Console.WriteLine("Please insert any number...");
// Read io and try to parse it to int
bool parseOk = int.TryParse(Console.ReadLine(), out int num);
// If the user did not provide any number, let him retry
if (!parseOk)
{
Console.WriteLine("Incorrect input. Please insert numbers only.");
continue;
}
// If the user typed in a valid number and that number is zero, break out of the loop
if (parseOk && num == 0)
{
break;
}
// If the user typed in a valid number and that number is smaller than the minimum-value, set the new minimum
if (parseOk && num < minValue)
{
minValue = num;
}
}
// Print the result to the console
Console.WriteLine($"Minimum value: {minValue}.");
// Keep console open
Console.ReadLine();
}
}
}

Try This:
int input;
Console.Write("Enter number:");
input = Int32.Parse(Console.ReadLine());
int min = input;
while(true)
{
if (input == 0)
break;
if (min > input)
min = input;
Console.Write("Enter number:");
input = Int32.Parse(Console.ReadLine());
}
Console.WriteLine(min);
Console.ReadKey();
I hope it helps.

Related

How to do while loop/Do while loop with sentinel value with switch

Hello I am trying to figure out why my program is not working, it's supposed to output a program in which department codes would be entered and followed by a prompt to enter a mark and so on until Q is entered. I can't seem to get that part working at all. If anyone could help please I will appreciate it.
// declare variables
char deptCode = ' ';
int count = 0;
double markVal, sum = 0, average = 0.0;
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘B’ or ‘b’ for History, ‘P’ or ‘p’ for Physics, or enter ‘Q’ or ‘q’ to quit:");
deptCode = Convert.ToChar(Console.ReadLine());
while (char.ToUpper(deptCode) != 'Q')
do
{
Console.Write("Enter a mark between 0 and 100 => ");
markVal = Convert.ToDouble(Console.ReadLine());
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘B’ or ‘b’ for History, ‘P’ or ‘p’ for Physics, or enter ‘Q’ or ‘q’ to quit:");
deptCode = Convert.ToChar(Console.ReadLine());
} while (markVal >= 0 && markVal <= 100);
count++;
average = (double)sum / count;
Console.WriteLine("***Error, Please Enter Valid Mark");
Console.WriteLine("The Average mark for Computer Science Students is {0}", average);
Console.WriteLine("The Average mark for Biology Students is {0}", average);
Console.WriteLine("The Average mark for Physics Students is {0}", average);
Console.ReadLine();
{
I am sympathetic to your dilemma and know it can be challenging to learn coding when you are not familiar with it. So hopefully the suggestions below may help to get you started at least down the right path. At the bottom of this is a basic “shell” but parts are missing and hopefully you will be able to fill in the missing parts.
One idea that you will find very helpful is if you break things down into pieces (methods) that will make things easier to follow and manage. In this particular case, you need to get a handle on the endless loops that you will be creating. From what I can see there would be three (3) possible endless loops that you will need to manage.
An endless loop that lets the user enter any number of discipline marks.
An endless loop when we ask the user which discipline to use
And an endless loop when we ask the user for a Mark between 0 and 100
When I say endless loop I mean that when we ask the user for a Discipline or a Mark… then, the user MUST press the “c”, “b” “p” or “q” character to exit the discipline loop. In addition the user MUST enter a valid double value between 0 and 100 to exit the Mark loop. The first endless loop will run allowing the user to enter multiple disciplines and marks and will not exit until the user presses the q character when selecting a discipline.
And finally when the user presses the ‘q’ character, then we can output the averages.
So to help… I will create two methods for you. One that will represent the endless loop for getting the Mark from the user… i.e.…. a number between 0 and 100. Then a second endless loop method that will get the Discipline from the user… i.e. … ‘c’, ‘b’, ‘p’ or ‘q’… and it may look something like…
private static char GetDisciplineFromUser() {
string userInput;
while (true) {
Console.WriteLine("Enter a department code: ‘C’ for Computer Science,‘B’ for Biology, ‘P’ for Physics, or enter ‘Q’ to quit:");
userInput = Console.ReadLine().ToLower();
if (userInput.Length > 0) {
if (userInput[0] == 'c' || userInput[0] == 'b' ||
userInput[0] == 'p' || userInput[0] == 'q') {
return userInput[0];
}
}
Console.WriteLine("Invalid discipline => " + userInput + " try again.");
}
}
Note… the loop will never end until the user selects the characters ‘c’, ‘b’, ‘p’ or ‘q’. We can guarantee that when we call the method above, ONLY those characters are returned.
Next is the endless loop to get the Mark from the user and may look something like…
private static double GetMarkFromUser() {
string userInput;
while (true) {
Console.WriteLine("Enter a mark between 0 and 100 => ");
userInput = Console.ReadLine().Trim();
if (double.TryParse(userInput, out double mark)) {
if (mark >= 0 && mark <= 100) {
return mark;
}
}
Console.WriteLine("Invalid Mark => " + userInput + " try again.");
}
}
Similar to the previous method, and one difference is we want to make sure that the user enters a valid number between 0 and 100. This is done using a TryParse method and most numeric types have a TryParse method and I highly recommend you get familiar with it when checking for valid numeric input.
These two methods should come in handy and simplify the main code. So your next issue which I will leave to you, is how are you going to store these values? When the user enters a CS 89 mark… how are you going to store this info? In this simple case… six variables may work like…
int totalsCSMarks = 0;
int totalsBiologyMarks = 0;
int totalsPhysicsMarks = 0;
double totalOfAllCSMarks = 0;
double totalOfAllBiologyMarks = 0;
double totalOfAllPhysicsMarks = 0;
Now you have something to store the users input in.
And finally the shell that would work using the methods above and you should see this uncomplicates things a bit in comparison to your current code. Hopefully you should be able to fill in the missing parts. Good Luck.
static void Main(string[] args) {
// you will need some kind of storage for each discipline.. see above...
char currentDiscipline = 'x';
double currentMark;
while (currentDiscipline != 'q') {
currentDiscipline = GetDisciplineFromUser();
if (currentDiscipline != 'q') {
currentMark = GetMarkFromUser();
switch (currentDiscipline) {
case 'c':
// add 1 to total number of CS marks
// add currentMarkValue to the total of CS marks
break;
case 'b':
// add 1 to total number of Biology marks
// add currentMarkValue to the total of Biology marks
break;
default: // <- we know for sure that only p could be left
// add 1 to total number of Physics marks
// add currentMarkValue to the total of Physics marks
break;
}
}
}
Console.WriteLine("Averages ------");
//Console.WriteLine("The Average mark for Computer Science Students is {0}", totalOfAllCSMarks / totalCSMarks);
//Console.WriteLine("The Average mark for Biology Students is {0}", ...);
//Console.WriteLine("The Average mark for Physics Students is {0}", ...);
Console.ReadLine();
}

How to fix while loop stopping + unhandled exception error

While loops runs through the if statement once and stops.
I am new to c#, so excuse me if I am overlooking something seemingly obvious. I am currently writing a program that visualizes the Collatz conjecture through console entries. The program begins by prompting the user to enter a natural number. The program is supposed to run that number through the formulae of the conjecture until it eventually reaches a value of 1. However, when I type in the number in console, the program runs it through one formula and crashes. It seems that is has a problem with the Double.Parse line. I already tried using the convert method and tried defining "num" as a decimal instead of a double.
{
Console.WriteLine("Enter a natural number:");
Double num = Convert.ToDouble(Console.ReadLine());
while (num != 1)
{
{
if (num % 2 == 0)
{
Console.WriteLine(num / 2);
num = Double.Parse(Console.ReadLine());
}
else
{
Console.WriteLine(num * 3 + 1);
num = Double.Parse(Console.ReadLine());
}
}
Console.ReadLine();
}
}
}
}
To be honest, I'm not positive what you're trying to achieve from the description (i.e., I have not idea what a Collatz conjecture visualization formula is), but I think I figured out what your issue is.
I think you're a little confused about Console.ReadLine(). This method pauses and waits for user input. As a result, during your first loop through the while statement, your program will pause and wait for user input. I think what you're trying to do is take the result of the formula in either the "if" or "else" section and capture that as the new value of "num."
Here is my best guess at what you're trying to achieve:
static void Main(string[] args)
{
Console.WriteLine("Enter a natural number:");
Double num = Convert.ToDouble(Console.ReadLine());
while (num != 1)
{
if (num % 2 == 0)
{
num /= 2;
Console.WriteLine(num);
}
else
{
num = num * 3 + 1;
Console.WriteLine(num);
}
}
Console.WriteLine(num);
Console.ReadLine();
}
Also, it looks like you might have an extra set of brackets within your while statement. It doesn't seem like that would compile as-is, so perhaps it is just the way in which you copied it into your question.

Constructing a MasterMind game without using Arrays in c#?

I am trying to create a mastermind game without using arrays that generates 5 random numbers 1-9, and you have 15 tries to guess them.*=Correct -=WRONG +=incorrect positionbut the number is right.
I created the first part of it, and it works for trying to guess the first random digit of 1-9. I am unsure of how to goto the second number for the player to guess the second 1-9 digit, and how to make the code keep using the same int's/keep adding onto the guesses that I set up already. I tried everyway I knew how and I can't figure it out. If I could get some assistance of where I am going wrong, and how to set it up correctly it would be very much appreciated. Cheers
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Decisions
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Guess the 5 Digit code, Under 15 tries!");
Random myRandom = new Random();
Int32 one = myRandom.Next(1, 10);
Int32 two = myRandom.Next(1, 10);
Int32 three = myRandom.Next(1, 10);
Int32 four = myRandom.Next(1, 10);
Int32 five = myRandom.Next(1, 10);
int guesses = 0;
bool incorrect = true;
do
{
if (guesses < 15)
Console.WriteLine("Guess a number between 1 and 9");
string result = Console.ReadLine();
guesses++;
if (guesses > 15)
Console.WriteLine("You went over 15 tries! Better luck next time");
if (result == one.ToString())
incorrect = false;
else if (result == two.ToString())
Console.WriteLine("+");
else if (result == three.ToString())
Console.WriteLine("+");
else if (result == four.ToString())
Console.WriteLine("+");
else if (result == five.ToString())
Console.WriteLine("+");
else
Console.WriteLine("-");
} while (incorrect);
if (guesses < 15)
Console.WriteLine("*Correct! It took {0} guesses.", guesses);
if (guesses > 15)
Console.WriteLine("You took to many tries! Better luck next time! Total Guesses: {0}", guesses);
Console.ReadLine();
}
}
}
I think what you're looking to use is a list. But first -
Keep in mind you want to be careful about how you order things in your program, especially when it comes to user experience. For instance:
if (guesses < 15)
Console.WriteLine("Guess a number between 1 and 9");
string result = Console.ReadLine();
guesses++;
if (guesses > 15)
Console.WriteLine("You went over 15 tries! Better luck next time");
So, when guesses is 14, it will show the text, have the user guess and increment "guesses" - however, when it iterates back to the beginning, your program will skip over the prompt: "Guess a number between 1 and 9" - but it will still wait for the users input. After they put in their input it will prompt that they went over the amount of tries, but it will still check if that number matched! How you order your program can be very important to a users experience.
Your program can look something like this:
const int iMaxGuesses = 15;
const int iListSize = 5;
static void Main(string[] args)
{
Random myRandom = new Random();
// Hold a list of integers
List<int> numbers = new List<int>();
int guesses = 0;
// Value where we will rebuild the code
string result = string.Empty;
// Placeholder for user's guess
string strGuess;
// Converted guess
int guess;
// Generate random list of numbers
for (int i = 0; i < iListSize; i++)
numbers.Add(myRandom.Next(1, 10));
// Prompt user
Console.WriteLine("Guess the {0} Digit code, Under {1} tries!", iListSize, iMaxGuesses);
// Open the game loop
do
{
// Check if we have exceeded the max amount of times we get to guess
if (guesses > iMaxGuesses)
Console.WriteLine("You went over 15 tries! Better luck next time");
else
{
// Prompt user
Console.WriteLine("Guess a number between 1 and 9");
// Get input
strGuess = Console.ReadLine();
// Check if input is in fact an integer, if so - put the value in our variable 'guess'
if (int.TryParse(strGuess, out guess))
{
// We have a proper guess, increment
guesses++;
// Checks if the number is the next in our list
if (numbers[0] == guess)
{
Console.WriteLine("Congratulations, {0} was a match!", guess);
// Remove that from the List
numbers.Remove(numbers[0]);
// Add it to our sequence (result)
result += guess;
}
else if(numbers.Contains(guess))
Console.WriteLine("Right number, wrong spot!");
else
Console.WriteLine("Incorrect, please try again!");
}
else // Inform user we will only accept numbered input
Console.WriteLine("That was not a number. Please try again!");
}
} while (guesses <= iMaxGuesses && numbers.Count > 0);
if (guesses < iMaxGuesses)
Console.WriteLine("Correct! It took {0} guesses to come up with the pattern {1}", guesses, result);
else
Console.WriteLine("You took to many tries! Better luck next time! Total Guesses: {0}", guesses);
Console.ReadLine();
}
Couple things to note: We have class-level constants for the List Size (we'll get to that) and how many guesses, in case these need to be changed on the fly. You can ignore this.
The first thing you may notice is a List of integers List<int> numbers = new List<int>() Here is some Reading (what is difference between string array and list of string in c#) about the differences between Arrays and Lists (collections).
We initialize the list of Random numbers by creating a loop the max size of our list, and ADDING a random integer to that list.
On the Do/While loop, we are checking that we are still less than iMaxGuesses and we have objects left in our list. So we take the users input. First we use int.TryParseto determine if we do actually have a number. If we do have a number, we will check that against the first number that appears in the list, numbers[0], and if it does, we remove it from the list: numbers.Remove(numbers[0]); The cool part about lists, is that when you REMOVE an item, it resizes the list, unlike an array that has a fixed size. So if your list is 12345, and you remove the 1, the next time you check the value of numbers[0], it will be 2!
I'm pretty sure the rest should be self explanatory. Let me know if anything was missed or you need help understanding anything.

How to block the user from typing text

I'm recreating the game Hammurabi (just an assignment for my uni) and I want somehow my code to check if the user is typing text so it gets in a while loop to prompt him to type text. I know how to make the user type the numbers I want him to but I don't know how to fix it if he types something like "a" then my program will bug.
Here is an example of what I'm talking about:
while (acresToBuy < 0)
{
Console.WriteLine("Please type a positive number or 0");
acresToBuy = int.Parse(Console.ReadLine());
}
int cost = trade * acresToBuy;
while (cost > bushels)
{
Console.WriteLine("We have but " + bushels + " bushels of grain, not " + cost);
acresToBuy = int.Parse(Console.ReadLine());
cost = trade * acresToBuy;
}
You can use Int.TryParse for this. For example:
while (acresToBuy < 0)
{
Console.WriteLine("Please type a positive number or 0");
acresToBuy = int.TryParse(Console.ReadLine(), out acresToBuy) ? acresToBuy : -1;
}
If Int.TryParse fails, then the method will return false, in which then we assign -1 to acresToBuy, otherwise, if it succeeds, we simply assign it back to itself.
You shouldn't use int.Parse (or other types' equivalents) unless you can absolutely guarantee that the input will be parsable, and that's something you cannot do where user input is involved. Instead, you should use int.TryParse:
do
{
Console.WriteLine("Please type a positive number or 0");
int input;
if (int.TryParse(Console.ReadLine(), out input)
&& input >= 0) // You can validate the input at the same time
{
acresToBuy = input;
}
else
{
Console.WriteLine("That was not the correct input. Please try again.");
acresToBuy = -1;
}
} while (acresToBuy < 0);
Edit: The while loop will always check it's condition first before executing, so keep in mind that your code will only run if acresToBuy has an initial value of something less than 0 (i.e. -1). To prevent from having to constantly check this against pre-existing conditions, you should instead use a do-while loop, which will always run at least once.

Adding to lists and loops

I've developed a new found interest in programming however I have had some problems. I have tried to make a simple program in which a user enters 10 numbers, if the number is 0 it will stop, then adds those numbers to a list then prints the list at the end. However, my program only asks for 4 numbers before stopping, it doesn't stop when 0 is entered and the "Enter a number message" at the start prints 3 times each time it goes round the loop.
Any help would be appreciated
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args) {
// I want to make a list
// keep asking the user for values
// which will then add those values onto the list
// then print the list
// create a list
List<int> list = new List<int>();
int count = 0;
while (count < 10) {
Console.WriteLine("Enter a value to add to the list");
int number = Console.Read();
list.Add(number);
if (number == 0) {
break;
}
count++;
}
Console.WriteLine("The final list looks like this");
foreach (int number in list) {
Console.WriteLine(number);
Console.ReadLine();
}
}
}
}
The problem is with Console.Read() - It reads a byte rather than a string that should be converted into int in your case.
What you're looking for is Console.ReadLine(), surrounded with int.Parse(). Something like this:
int number = int.Parse(Console.ReadLine());

Categories

Resources