How to transfer the control of goto statement in C# - c#

I'm beginner in programming and I'm trying this simple program of getting user name and sorting it and so on.
class Program
{
static void Main(string[] args)
{
int number;
dynamic y;
string[] answer = new string[10];
cases:
Console.WriteLine("Enter the options given below 1.Add students\n 2.View all details\n 3.Sorting\n 4.Exit\n");
int input = Convert.ToInt16(Console.ReadLine());
switch (input)
{
case 1:
Console.WriteLine("Enter the Number of Students to be added to the List");
number = Convert.ToInt16(Console.ReadLine());
for (int i = 0; i < number; i++)
{
answer[i] = Console.ReadLine();
}
case 2:
foreach (var item in answer)
{
Console.WriteLine(item.ToString());
}
break;
case 3:
Array.Sort(answer);
foreach (var item in answer)
{
Console.WriteLine(item.ToString());
}
break;
case 4:
Console.WriteLine("Are you sure you want to exit");
Console.WriteLine("1 for Yes and N for No");
y = (char)Console.Read();
if ((y == 1))
{
goto cases;
}
else
{
goto thankyou;
}
thankyou:
Console.WriteLine("thank you");
break;
}
Console.WriteLine("Are you sure you want to exit");
Console.WriteLine("Y for Yes and 1 for No");
y = (char)Console.Read();
if ((y == 1))
{
goto cases;
}
else
{
goto thankyou;
}
}
}
My problem is that after every operation I have ask whether it should continue or not. I have added go-to statements but when pressed No its shows an exception for input variable that I have declared.
Can I use the go-to method or Is there any way we can do this ?
Any suggestions what is wrong here??

If you want a loop in your program you should use one of the loop constructs in C#. In this case a while loop would work:
bool keepPrompting = true;
while(keepPrompting) {
Console.WriteLine("Enter the options given below 1.Add students\n 2.View all details\n 3.Sorting\n 4.Exit\n");
int input = Convert.ToInt16(Console.ReadLine());
// The case statement on input goes here
Console.WriteLine("Are you sure you want to exit");
Console.WriteLine("Y for Yes and 1 for No");
var y = (char)Console.Read();
if (y != 'y')
keepPrompting = false;
}
Console.WriteLine("thank you");
goto is almost never used in C# (or any other language) for that matter because it's hard to follow a program that can jump around to almost any location while a loop has a defined flow.

You shouldn't do this with goto. You should always avoid goto entirely. If you think for some reason that you need to use goto, you should find a way to do it without goto. Here's an example of how to do this while avoiding goto.
class Program
{
static void Main(string[] args)
{
int number;
dynamic y;
string[] answer = new string[10];
bool result = false;
while(!result) {
Console.WriteLine("Enter the options given below 1.Add students\n 2.View all details\n 3.Sorting\n 4.Exit\n");
int input = Convert.ToInt16(Console.ReadLine());
switch (input)
{
case 1:
Console.WriteLine("Enter the Number of Students to be added to the List");
number = Convert.ToInt16(Console.ReadLine());
for (int i = 0; i < number; i++)
{
answer[i] = Console.ReadLine();
}
break;
case 2:
foreach (var item in answer)
{
Console.WriteLine(item.ToString());
}
break;
case 3:
Array.Sort(answer);
foreach (var item in answer)
{
Console.WriteLine(item.ToString());
}
break;
case 4:
Console.WriteLine("Are you sure you want to exit");
Console.WriteLine("1 for Yes and N for No");
result = ((char)Console.Read()) == 'y';
break;
}
}
Console.WriteLine("thank you");
}
}
}

static void Main(string[] args)
{
// First you need a few loops, avoid goto's at all costs they make code much harder to read
// There are better ways to do this but this will get it done
// List<string> answer = new List<string>(); would be better here because it resizes automatically when adding
// I left it like this because it looks like a school project
List<string> answer = new List<string>(); // create variable before loops so it is not recreated on each iteration
bool exit = false; // create bool variable and use it to exit infinite loop by setting it to true when user chooses option 4
for (;;) // create outer infinit loop to so the code will execute until you want you break; when option 4 is entered
{
int option;
for (;;)// create infinite loop to get user input for which option they want
{
Console.Clear();
Console.WriteLine("Enter the options given below\n1.Add students\n2.View all details\n3.Sorting\n4.Exit\n");
if (int.TryParse(Console.ReadLine(), out option) && option >= 1 && option <= 4)
{ break; /*user entered valid option so we break from this infinit loop*/ }
else
{ Console.Clear(); /*User did not enter a valid option so clear the console window*/ }
}
switch (option) // switch cases to handle each of the possible options entered
{
case 1:
// user chose option 1
int number = 0;
while (number <= 0)
{
Console.Clear();
Console.WriteLine("Enter the number of students to add.");
int.TryParse(Console.ReadLine(), out number);
// Because "answer" is now a list it does not have to be sized
for(int i=0;i<number;i++)
{
Console.Clear();
Console.WriteLine("Enter Name: ");
// with a list, the previous list of students are not wiped out
// we also don't have to be carefull about writing outside array bounds because of the add method
answer.Add(Console.ReadLine());
}
}
break; // break out of case 1
case 2:
// user chose option 2
break;// break out of case 2
case 3:
// user chose option 3
if (answer.Count > 0)
{
Console.Clear();
Console.WriteLine("Sorted student names:");
answer.Sort(); // List<string> have a Sort member method
Console.WriteLine(string.Join("\n", answer));
}
else
{ Console.WriteLine("No students exist to sort or list."); }
Console.ReadLine(); // pause screen for reading
break;// break out of case 3
case 4:
// user chose option 4
while (true) // loop until a Y or 1 is entered
{
Console.WriteLine("Are you sure you want to exit\nY for YES and 1 for NO");
char y = (char)Console.Read();
if (y == 'Y' || y == 'y')
{ exit = true; break; /*user is sure they want to exit*/ }
else if (y == '1')
{ Console.Clear(); break; /*user decided not to exit*/ }
else
{ Console.Clear(); }
}
break; // break out of case 4
}
if (exit) break; // if exit variable true then break out of outer infinite loop
}
}

static void Main(string[] args)
{
// First you need a few loops, avoid goto's at all costs they make code much harder to read
// There are better ways to do this but this will get it done
// List<string> answer = new List<string>(); would be better here because it resizes automatically when adding
// I left it like this because it looks like a school project
string[] answer = new string[0]; // create variable before loops so it is not recreated on each iteration
bool exit = false; // create bool variable and use it to exit infinite loop by setting it to true when user chooses option 4
for (;;) // create outer infinit loop to so the code will execute until you want you break; when option 4 is entered
{
int option;
for (;;)// create infinite loop to get user input for which option they want
{
Console.Clear();
Console.WriteLine("Enter the options given below\n1.Add students\n2.View all details\n3.Sorting\n4.Exit\n");
if (int.TryParse(Console.ReadLine(), out option) && option >= 1 && option <= 4)
{ break; /*user entered valid option so we break from this infinit loop*/ }
else
{ Console.Clear(); /*User did not enter a valid option so clear the console window*/ }
}
switch (option) // switch cases to handle each of the possible options entered
{
case 1:
// user chose option 1
int number = 0;
while (number <= 0)
{
Console.Clear();
Console.WriteLine("Enter the number of students to add.");
int.TryParse(Console.ReadLine(), out number);
answer = new string[number]; // re-initize number of students to add
for(int i=0;i<number;i++)
{
Console.Clear();
Console.WriteLine("Enter Name: ");
answer[i] = Console.ReadLine();
}
}
break; // break out of case 1
case 2:
// user chose option 2
break;// break out of case 2
case 3:
// user chose option 3
if (answer.Length > 0)
{
Console.Clear();
Console.WriteLine("Sorted student names:");
Array.Sort(answer);
Console.WriteLine(string.Join("\n", answer));
Console.ReadLine(); // pause screen for reading
}
break;// break out of case 3
case 4:
// user chose option 4
while (true) // loop until a Y or 1 is entered
{
Console.WriteLine("Are you sure you want to exit\nY for YES and 1 for NO");
char y = (char)Console.Read();
if (y == 'Y' || y == 'y')
{ exit = true; break; /*user is sure they want to exit*/ }
else if (y == '1')
{ Console.Clear(); break; /*user decided not to exit*/ }
else
{ Console.Clear(); }
}
break; // break out of case 4
}
if (exit) break; // if exit variable true then break out of outer infinite loop
}
}

Related

I have a sentinel while loop with if statments inside them, I want to break out of the if statements without breaking out of the while loop C#

I am supposed to use only a sentinel while loop for an assignment. The user is meant to enter a department code, and for each department code its supposed to intake a mark and then at the end when the while loop is exited it calculates the average. My question is can I break out an an If statement inside a while loop without breaking out of the while loop itself? And once Q is pressed exit out of the program?
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘M’ or " +
"‘m’ for Math, ‘B’ or ‘b’ for Business Admin, or enter ‘Q’ or ‘q’ to quit => C");
char deptCode = Console.ReadKey().KeyChar;
while (char.ToUpper(deptCode) != 'Q')
{
if (char.ToUpper(deptCode) == 'C')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
computerScienceMark = Convert.ToInt32(Console.ReadLine());
break;
}
else if (char.ToUpper(deptCode) == 'B')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
businessMark = Convert.ToInt32(Console.ReadLine());
break;
}
else if (char.ToUpper(deptCode) == 'M')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
mathMark = Convert.ToInt32(Console.ReadLine());
break;
}
if (char.ToUpper(deptCode) == 'Q')
{
Console.WriteLine("you entered Q to quit");
Environment.Exit(0);
}
else
{
Console.WriteLine("\nYou entered a wrong input please try again");
break;
}
}
You could put the whole request for a department code inside a while.
That way the users will be asked for a new code until they enter 'Q', like this
while (true)
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘M’ or ‘m’ for Math, ‘B’ or ‘b’ for Business Admin, or enter ‘Q’ or ‘q’ to quit => C");
char deptCode = Console.ReadLine()[0];
if (char.ToUpper(deptCode) == 'Q')
break;
if (char.ToUpper(deptCode) == 'C')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
computerScienceMark = Convert.ToInt32(Console.ReadLine());
}
else if (char.ToUpper(deptCode) == 'B')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
businessMark = Convert.ToInt32(Console.ReadLine());
}
else if (char.ToUpper(deptCode) == 'M')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
mathMark = Convert.ToInt32(Console.ReadLine());
}
else
{
Console.WriteLine("\nYou entered a wrong input please try again");
}
}
https://www.jdoodle.com/iembed/v0/8Wi
You want two loops. One outer one to get the department codes, and one inner one to get the mark. Something along the lines of:
static void Main(string[] args)
{
while (true) // outer loop
{
string department;
Console.WriteLine("Enter department code:");
department = Console.ReadLine().ToUpper();
if (department == "Q")
{
break; // end the outer loop
}
else if (department == "C"
|| department == "B"
|| department == "M")
{
while (true) // inner loop
{
int mark;
Console.WriteLine("Enter mark:");
if (int.TryParse(Console.ReadLine(), out mark)
&& mark >= 0
&& mark <= 100))
{
break; // end the inner loop;
}
else
{
Console.WriteLine("Invalid mark. Try again.");
}
}
}
else
{
Console.WriteLine("Invalid department code. Try again.");
}
}
}
To end the outer loop check if department was "Q" and break. For the inner one break when the mark was correctly entered. You can use int.TryParse() to check if the string entered really represents an integer for that check.
bool check = false;
while (check == false)
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘M’ or ‘m’ " +
"for Math, ‘B’ or ‘b’ for Business Admin, or enter ‘Q’ or ‘q’ to quit => C");
char deptCode = Console.ReadLine()[0];
if (char.ToUpper(deptCode) == 'Q')
{
check = true;
}
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
switch (char.ToUpper(deptCode))
{
case 'C':
computerScienceMark = Convert.ToInt32(Console.ReadLine());
check = true;
break;
case 'B':
businessMark = Convert.ToInt32(Console.ReadLine());
check = true;
break;
case 'M':
mathMark = Convert.ToInt32(Console.ReadLine());
check = true;
break;
default:
Console.WriteLine("\nYou entered a wrong input please try again");
break;
}
}
To a consenus it is bad programing form to use break, continue, goto and such. Don't let me tell you how to program, use whatever you like and be my guest. However, if you're a beginner and wanting to learn transferable skills it's genuinely regarded as sloppy to use break - this is because it can leave behind "un tided up" (for lack of a better expression) memory. I only mean when using break when in an iteration.
My soultion is very similar to Jack Lilhammers, although I prefer the switch statement here, it's a little neater. Furthermore, using an idividual variable for the while condition is a nice idea because it's a good habbit to get acustomed with when doing larger more complex while loops where u might find yourself stepping throught the code and having that variable allows you to nicely observe it's state throughout.

Adding switch case

I want to add switch case to not allow the user to write string when entering temperature or when there is nothing to delete it says "there is nothing to delete, go back to menu".
List<string> Temp = new List<string>();
while (true)
{
string val;
Console.WriteLine("[L] ägg till temp-mätning: ");
Console.WriteLine("[S] kriv ut alla temperaturer och medeltemperatur");
Console.WriteLine("[T] ag bort temp-mätning");
Console.WriteLine("[A] vsluta");
Console.Write("Selection: ");
val = Console.ReadLine();
if (val == "l" || val == "L")
{
Console.WriteLine("add temperature : ");
Temp.Add(Console.ReadLine());
Console.Clear();
}
else if(val == "s" || val == "S")
{
int index = 1;
Console.Clear();
Console.WriteLine($"Your temperatures are: ");
Temp.ForEach(x => Console.WriteLine($"{index++} - {x}"));
}
else if (val == "t" || val == "T")
{
Console.Write($"Which temp do you want to delete [index from 1 to {Temp.Count}]: ");
int deleteIndex = int.Parse(Console.ReadLine()) - 1;
Temp.RemoveAt(deleteIndex);
}
else
{
Console.WriteLine("incorrect input: ");
Console.Clear();
break;
}
To control use input you can extract methods, e.g.
private static int ReadInteger(string title) {
while (true) {
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
if (int.TryParse(Console.ReadLine(), out int result))
return result;
Console.WriteLine("Incorrect syntax, please, try again.");
}
}
then you can put
val = Console
.ReadLine()
.Trim() // Let's be nice and tolerate leading / trailing spaces, e.g. " L "
.ToUpper();
val = val.Substring(0, Math.Max(1, val.Length));
switch (val) {
case "L":
// We read valid integer, turn it to string and out to Temp
Temp.Add(ReadInteger("add temperature : ").ToString());
Console.Clear();
break;
case "T":
int deleteIndex = ReadInteger(
"$"Which temp do you want to delete [index from 1 to {Temp.Count}]: ");
if (deleteIndex >= 0 && deleteIndex < Temp.Count)
Temp.RemoveAt(deleteIndex);
else
Console.WriteLine("Index out of range");
break;
...
}
Please check C# reference websites or books before asking questions.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/
Here is the code you wanted, hope this helps you:
List<string> Temp = new List<string>();
while (true)
{
menu:
string val = string.Empty;
Console.WriteLine("[L] ägg till temp-mätning: ");
Console.WriteLine("[S] kriv ut alla temperaturer och medeltemperatur");
Console.WriteLine("[T] ag bort temp-mätning");
Console.WriteLine("[A] vsluta");
Console.Write("Selection: ");
val = Console.ReadLine();
switch (val.ToLower())
{
case "l":
addTemperature:
Console.WriteLine("add temperature : ");
string temperatureInput = Console.ReadLine();
int temperatureToAddToList;
try
{
temperatureToAddToList = Convert.ToInt32(temperatureInput); //This line trys to convert string variables to integer variables. If string variable includes any character, it will throw an exception.
}
catch (Exception error) //If an exception was thrown, this code block gets activated, which will give out the message you asked for.
{
Console.Clear();
Console.WriteLine("Please enter a number instead of a string!");
goto addTemperature;
}
Temp.Add(temperatureInput.Trim());
Console.Clear();
break;
case "s":
int index = 1;
Console.Clear();
Console.WriteLine($"Your temperatures are: ");
Temp.ForEach(x => Console.WriteLine($"{index++} - {x}"));
break;
case "t":
if (Temp.Count == 0)
{
Console.Clear();
Console.WriteLine("There is nothing to delete, go back to menu.");
goto menu;
}
else
{
Console.Write($"Which temp do you want to delete [index from 1 to {Temp.Count}]: ");
int deleteIndex = int.Parse(Console.ReadLine()) - 1;
Temp.RemoveAt(deleteIndex);
break;
}
default:
Console.WriteLine("incorrect input: ");
Console.Clear();
break;
}
I have revised and updated my code example to better solve your problem.

Return to a specific block of code in my application

I am fairly new to C# and currently building a simple ATM app. I am attempting to write code to return the user to the main menu according to his/her entry of the letter M. The break, continue, goto or return keywords do not seem to work in my scenario; perhaps I used them incorrectly. The statement directly below is where I would like to jump to.
Console.WriteLine("Select an option? \n VIEW BALANCE (B1) checking, (B2) saving \n DEPOSIT (C1) checking, (C2) saving \n WITHDRAW (W1) checking, (W2) saving");
I would like to jump from the line JUMP (below) within the else if statement nested within the switch statement into the section of code above. How can I achieve this? any help is appreciated...thanks!
switch (response)
{
case "C1":
Console.WriteLine("How much would you like to deposit to your checking account?");
string depositEntry = Console.ReadLine();
double checkingBalance = Convert.ToInt32(depositEntry) + currentCheckingBalance;
currentCheckingBalance += checkingBalance;
Console.WriteLine("Your current checking balance is " + checkingBalance + "\n (X) Exit, (M) Main Menu" );
string selection = Console.ReadLine().ToUpper();
if (selection == "X")
{
return;
}
else if (selection == "M")
{
***JUMP***
}
else
{
Console.WriteLine("Your entry was invalid");
}
break;
case "C2":
break;
case "W1":
Using a jump statement usually indicates the flow of logic is jumbled. I try to avoid any kind of jumps if necessary. The code below prints out a main menu and if the user types “x” the program will quit. If the user selects one of the other options, a message is simply printed out indicating what the user selected. After the user presses any key, the console clears and the main menu is re-displayed.
In the main menu, if the user does not type one of the selections, then the selection is ignored, the console is cleared, and the menu is reprinted. No error is displayed indicating invalid selections.
This does not require the user to type “m” to go back to the main menu. After a selection is made for Deposit/withdraw/… after the method is finished the code will automatically return to the main menu.
I am guessing this may be what you are looking for. Hope this helps.
static void Main(string[] args) {
string userInput = "";
while ((userInput = GetMainSelection()) != "x") {
switch (userInput) {
case "c1":
Console.WriteLine("C1 Deposit Checking method");
break;
case "c2":
Console.WriteLine("C2 Deposit Savings method");
break;
case "b1":
Console.WriteLine("B1 View Balance Checking method");
break;
case "b2":
Console.WriteLine("B2 View Balance Savings method");
break;
case "w1":
Console.WriteLine("W1 Withdraw Checking method");
break;
case "w2":
Console.WriteLine("W2 withdraw Savings method");
break;
}
Console.WriteLine("Press Any Key to continue"); // <-- show what method was just used
Console.ReadKey();
Console.Clear();
}
Console.Write("Press any key to exit the program");
Console.ReadKey();
}
private static string GetMainSelection() {
string userInput = "";
while (true) {
Console.WriteLine("Select an option? \n VIEW BALANCE (B1) checking, (B2) saving \n DEPOSIT (C1) checking, (C2) saving \n WITHDRAW (W1) checking, (W2) saving. (X) to EXit");
userInput = Console.ReadLine().ToLower();
if (userInput == "b1" || userInput == "b2" || userInput == "c1" || userInput == "c2" || userInput == "w1" || userInput == "w2" || userInput == "x") {
return userInput;
}
else {
Console.Clear();
}
}
}
Put the JUMP code in a function and return.
public void MainMenu() {
// Show the main menu
}
public void Response(string response) {
switch (response)
{
case "C1":
Console.WriteLine("How much would you like to deposit to your checking account?");
string depositEntry = Console.ReadLine();
double checkingBalance = Convert.ToInt32(depositEntry) + currentCheckingBalance;
currentCheckingBalance += checkingBalance;
Console.WriteLine("Your current checking balance is " + checkingBalance + "\n (X) Exit, (M) Main Menu" );
string selection = Console.ReadLine().ToUpper();
if (selection == "X")
{
return;
}
else if (selection == "M")
{
***JUMP***
MainMenu();
return;
}
else
{
Console.WriteLine("Your entry was invalid");
}
break;
case "C2":
break;
case "W1":
}
}
Similar to the already given answer, I suggest breaking this out. Here's an example:
The Main method:
static void Main(string[] args) {
string input = null;
do {
input = Console.ReadLine();
ParseInput(input);
} while (input != "X");
}
ParseInput:
static void ParseInput(string input) {
switch (input) {
case "X": //from Main(), this will close the app
return;
case "M":
MainMenu();
break;
case "C1":
ShowAccount("C1"); //move your deposit/withdraw logic into a method and call with the selected account
return;
//other accounts
default:
break; //error message?
}
}
and MainMenu:
static void MainMenu() {
Console.WriteLine("Select an option? \n VIEW BALANCE (B1) checking, (B2) saving \n DEPOSIT (C1) checking, (C2) saving \n WITHDRAW (W1) checking, (W2) saving");
}
This should let you read the input in a loop and the ParseInput function can handle your individual cases. You may also want to call MainMenu() at the start, so it shows from the beginning.
It works like this:
Get input from the user
Pass the input to ParseInput() which decides where to go next.
Any functions hit in ParseInput() will execute, writing to the console or asking for further input
Once that function returns, while (input != "X") evaluates. If input != "X", goto 1, else exit.
I suggest you use goto C# reference.
static void Main()
{
int x = 200, y = 4;
int count = 0;
string[,] array = new string[x, y];
// Initialize the array:
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
array[i, j] = (++count).ToString();
// Read input:
Console.Write("Enter the number to search for: ");
// Input a string:
string myNumber = Console.ReadLine();
// Search:
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
if (array[i, j].Equals(myNumber))
{
goto Found;
}
}
}
Console.WriteLine("The number {0} was not found.", myNumber);
goto Finish;
Found:
Console.WriteLine("The number {0} is found.", myNumber);
Finish:
Console.WriteLine("End of search.");
// Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
Output for the Input 44 would be:
Enter the number to search for: 44
The number 44 is found.
End of search.
See here for the MSDN reference.

How could I convert this goto into a do while loop?

class Program
{
static void Main(string[] args)
{
string choice = string.Empty;
do
{
start:
int output = 0;
int number = 0;
Console.WriteLine("Please input a number for it to be counted!");
bool conversion = int.TryParse(Console.ReadLine(), out output);
if (number < 1000)
{
switch (conversion)
{
case true:
while (number <= output)
{
Console.Write(number + " ");
number += 2;
}
break;
case false:
Console.WriteLine("ERROR: INVALID INPUT!");
goto start;
}
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
return;
}
do // Here is the beginning of the do code
{
Console.WriteLine("\n Do you want to continue - Yes or No");
choice = Console.ReadLine();
if (choice.ToUpper() != "YES" && choice.ToUpper() != "NO")
{
Console.WriteLine("ERROR INVALID INPUT: Only input Yes or No!");
}
} while (choice.ToUpper() != "YES" && choice.ToUpper() != "NO");
} while (choice.ToUpper() == "YES");
}
}
I'm using several do while loops in this statement however I'm trumped on how I would put in a loop "ERROR INVALID INPUT:" result when a user puts in anything other than the limits of the assigned integers (i.e. putting decimals or fractions) or if they put a string. I simply used goto because I'm having trouble finding out where to put the do while loop statement. If someone could simply show me how I might replace that one goto with a do while loop then I would be very greatful. (Note if you show me ways I could optimize my code better since I'm still new I probably won't understand it but your welcome to give it your best shot!)
Short answer:
The keyword continue means to go back to the beginning of the loop. Note that this will recheck the loop condition and break if it is false. Also, most people find do-while loops less readable (and they are really rarely necessary), so try using while loops instead.
There is also the keyword break which will simply exit the loop. (not just for switch-case!)
A more readable version would look something like this:
string userAnswer = "yes";
// while is usually more readable than do-while
while (userAnswer == "yes")
{
Console.WriteLine("Please input a number for it to be counted!");
int number;
// Ask for new input until the user inputs a valid number
while (!int.TryParse(Console.ReadLine(), out number))
{
Console.WriteLine("Invalid number, try again");
}
if (number < 1000)
{
// Print from 0 to number, jumping in 2's
for (int i = 0; i <= number; i += 2)
Console.WriteLine(i + " ");
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
continue; // Jump back to the start of this loop
}
Console.WriteLine("Continue? (Yes / No)");
userAnswer = Console.ReadLine().ToLower();
// Ask for new input until the user inputs "Yes" or "No"
while (userAnswer != "yes" && userAnswer != "no")
{
Console.WriteLine("Invalid input. Continue? (Yes / No)");
userAnswer = Console.ReadLine().ToLower();
}
}
Hey I'll post some code that may help and offer some advice. Basically declare a bool named 'loopCompleted' which will continue the do while loop until you set it to true. The downside is that it will not instantly exit the loop like return/goto/etc but this is not a problem in most cases.
You may want to use if/else instead of switch(conversion), its sort of interesting to see it done that way but its a bit over the top :)
If Int.TryParse() doesnt already return false for fractional values (e.g. [15.08] returns [true] with [15] ). Then you can store Console.ReadLine() before using TryParse, then use stringName.Contains() to check for the '.' Basically, if the conversion succeeds you also check if it contained the decimal point.
Another way to check is to do float.TryParse() then check if it is a fractional value.
bool fraction = false;
if( number % 1.0f > 0)
fraction == true;
% is called modulus, it returns the remainder of A / B
If a number has a remainder when divided by 1 it must be a fractional value.
//start:
bool loopCompleted = false;
do
{
int output = 0;
int number = 0;
Console.WriteLine("Please input a number for it to be counted!");
bool conversion = int.TryParse(Console.ReadLine(), out output);
if (conversion && number < 1000)
{
while (number <= output)
{
Console.Write(number + " ");
number += 2;
}
loopCompleted = true;
}
else
{
if(conversion == false)
{
Console.WriteLine("ERROR: INVALID INPUT!");
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
}
}
} while(!loopCompleted)

New to C#, not all code paths return a value, Bottle counting program, switch statement

Hello I've reached a stump that I cannot pull out.
My program records the number of bottles collected by four rooms. The program should prompt me to enter a room number and then how many bottles that room has collected. When ever the user types in "quit" the program will spit out the bottles collected by each room and calculate the room with the most bottles collected. I should be able to add bottles to each room as long as I haven't typed in quit.
I cannot get my GetRoom (int room) working, that is the method that does not return a value.
How would I find the room with the most bottles collected? Math.Max?
I cannot use LINQ or arrays. Its part of the assignment rules.
Heres is my code:
namespace BottleDrive1
{
class Program
{//Initialize 4 rooms.
int room1 = 0;
int room2 = 0;
int room3 = 0;
int room4 = 0;
static void Main(string[] args)
{
//Start of while loop to ask what room your adding into.
while (true)
{
Console.Write("Enter the room you're in: ");
//If user enters quit at anytime, the code will jump out of while statement and enter for loop below
string quit = Console.ReadLine();
if (quit == "quit")
//Break statement allows quit to jump out of loop
break;
}
}
private void SetRoom(int room, int value)
{
switch (room)
{
case 1:
room1 = value;
break;
case 2:
room2 = value;
break;
case 3:
room3 = value;
break;
case 4:
room4 = value;
break;
}
}
public void GetRoom(int room)
{
int count = int.Parse(Console.ReadLine());
switch (room)
{
case 1:
room1 += count;
break;
case 2:
room2 += count;
break;
case 3:
room3 += count;
break;
case 4:
room4 += count;
break;
default:
throw new ArgumentException();
}
}
}
}
You need to make sure your function returns something. Have you tried compiling this code? It has a compile error that would fix your method.
And Math.Max is a good way to find the max.
The problem is that your GetRoom method is defined to return an int and hence it must do so on every code path. This particular example doesn't return a value on any path.
Based on the logic within the GetRoom method though it seems like you're modifying rooms instead of returning one. If that's the case simply switch the method to return void
public void GetRoom() {
...
}
The GetRoom method does not return a value. Either provide a default value in a switch statement or and a return statement after that. Also, you can raise an exception in these cases.
Example:
public int GetRoom(int room)
{
int count = int.Parse(Console.ReadLine());
switch (room)
{
case 1:
room1 += count;
break;
case 2:
room2 += count;
break;
case 3:
room3 += count;
break;
case 4:
room4 += count;
break;
default:
throw new ArgumentException(); //either this
}
throw new ArgumentException(); //or this
}
BTW, you can use an array of 4 elements instead of 4 different variables, that will simplify your existing code and save you some time writing new. For example, GetRoom will look like this:
public int GetRoom(int room)
{
int count = int.Parse(Console.ReadLine());
rooms[room] += count;
//return what you need to return here
}
Here's an example that uses a Class to hold the information for each room. The reason for using a class is so that if your program needs to change in the future to collect more information, you won't have to track yet another array, you can just add properties to the class.
The individual rooms are now held in a list instead of an array just to show a different construct.
Here is the new Room class:
public class Room
{
public int Number { get; set; }
public int BottleCount { get; set; }
public Room(int wNumber)
{
Number = wNumber;
}
}
And here is the new version of the program. Note that additional checking of the values entered by the end user has been added in order to prevent exceptions when trying to get the current room or parse to an int the value entered by the user:
static void Main(string[] args)
{
const int MAX_ROOMS = 4;
var cRooms = new System.Collections.Generic.List<Room>();
for (int nI = 0; nI < MAX_ROOMS; nI++)
{
// The room number is 1 to 4
cRooms.Add(new Room(nI + 1));
}
// Initializes the room that wins
//Start of while loop to ask what room your adding into.
while (true)
{
Console.Write("Enter the room you're in: ");
//If user enters quit at anytime, the code will jump out of while statement and enter for loop below
string roomNumber = Console.ReadLine();
if (roomNumber == "quit")
{
//Break statement allows quit to jump out of loop
break;
}
int room = 0;
if (int.TryParse(roomNumber, out room) && (room < MAX_ROOMS) && (room >= 0)) {
Room currentRoom;
currentRoom = cRooms[room];
Console.Write("Bottles collected in room {0}: ", currentRoom.Number);
int wBottleCount = 0;
if (int.TryParse(Console.ReadLine(), out wBottleCount) && (wBottleCount >= 0))
{
// This line adds the count of bottles and records it so you can continuously count the bottles collected.
currentRoom.BottleCount += wBottleCount;
}
else
{
Console.WriteLine("Invalid bottle count; value must be greater than 0");
}
}
else
{
Console.WriteLine("Invalid room number; value must be between 1 and " + MAX_ROOMS.ToString());
}
}
Room maxRoom = null;
foreach (Room currentRoom in cRooms) //This loop goes through the array of rooms (4)
{
// This assumes that the bottle count can never be decreased in a room
if ((maxRoom == null) || (maxRoom.BottleCount < currentRoom.BottleCount))
{
maxRoom = currentRoom;
}
Console.WriteLine("Bottles collected in room {0} = {1}", currentRoom.Number, currentRoom.BottleCount);
}
//Outputs winner
Console.WriteLine("And the Winner is room " + maxRoom.Number + "!!!");
}
You are not returning anything from your function at all. Try something like this, store your result in a temporary variable then when you exit the function return it.
public int GetRoom(int room)
{
int count = int.Parse(Console.ReadLine());
int temp = 0;
switch (room)
{
case 1:
room1 += count;
temp = room1;
break;
case 2:
room2 += count;
temp = room2;
break;
case 3:
room3 += count;
temp = room3;
break;
case 4:
room4 += count;
temp = room4;
break;
default:
throw new ArgumentException();
}
return temp;
}

Categories