Problem with do while loop that jumps out despite false condition - c#

Newbie here! I've run into problems with some inconsistency when running the do while loop which surrounds the Try/Catch block.
Messing back and forth with different inputting makes the loop jump out despite its condition, which at multiple occasions should be true and run the block once again. Instead it ends up at "Number already exists" random number of times. It's obviously a hickup somewhere... Am I using it in the wrong way?
static void Main(string[] args)
{
int[] numbers = new int[10];
int input = 0;
int numRangeMin = 1;
int numRangeMax = 25;
bool duplicateNumber = false;
bool loop = true;
Console.WriteLine("\n Fill in a number:");
for (int i = 0; i < numbers.Length; i++)
{
do
{
do
{
try
{
Console.Write(" {0}: ", i + 1);
input = int.Parse(Console.ReadLine());
duplicateNumber = numbers.Contains(input); // Check if number already has been entered
loop = false;
}
catch (System.FormatException)
{ Console.WriteLine(" Only integers between {0}-{1} Try again!\n", numRangeMin, numRangeMax); }
catch (System.OverflowException)
{ Console.WriteLine(" Number is too big! Enter a number between {0}-{1}\n", numRangeMin, numRangeMax); }
} while (loop == true);
// Report if we attempt to insert a duplicate.
if (duplicateNumber)
{
Console.WriteLine("Number already exists");
}
else if (input > numRangeMax)
{
Console.WriteLine(" Too large:\n", numRangeMin, numRangeMax);
i--;
}
}
while (duplicateNumber == true); // Keep asking while we don't get a unique number.
numbers[i] = input; // Store the number
}
}

Your loop variable is defined outside the outer do loop, so it will retain it's value whenever you change it, that will lead to the inner loop not to be executed after the first time it has been set as false.
Define loop in side the outer loop or set it to true prior to the execution of the inner loop.
//...
do
{
loop = true;
do
{
try
{
//...
Also, the same will happen with the duplicateNumber variable because it's declared outside the for loop

Related

How to add objects to a list in a while loop with user input?

I've made this class:
public class Row
{
public string ID { get; set; }
public int Value { get; set; }
public Row(string id, int rowValue)
{
this.ID = id;
this.Value = rowValue;
}
}
And right now I'm adding objects to a list with the following code. It works, but the thing is I have to add those objects with an user input, something like I did with the 1st row AND while (TOTAL <= maxTotal). If next row I'm trying to add makes TOTAL more than maxTotal it is not added to the list. So I suppose I have to put that somehow in a while loop, but I can't seem to do it. I just started to learn C# and I can't find how to do it and I don't know if I'm on the right path.
public class Program
{
static void Main(string[] args)
{
List<Row> rows = new List<Row>();
int rowValue;
int TOTAL = 0;
int maxTotal = 100;
Console.Write("Insert row ID: ");
string id = Console.ReadLine();
Console.Write("Insert row value: ");
int.TryParse(Console.ReadLine(), out rowValue);
Row row1 = new Row(id, rowValue); // if this rowValue would be 20 then row3 shouldn't be added
Row row2 = new Row("BBB", 40);
Row row3 = new Row("CCC", 50);
rows.Add(row1);
rows.Add(row2);
rows.Add(row3);
for (int i = 0; i < rows.Count; i++)
{
TOTAL += rows[i].Value;
}
for (int i = 0; i < rows.Count; i++)
{
Console.WriteLine(rows[i].ID + " " + rows[i].Value);
}
}
}
Read the input in a loop and break out of the loop if total gets too large:
List<Row> rows = new List<Row>();
int total = 0;
int maxTotal = 100;
// The loop only ends when the `break` is hit later
while (true) {
Console.Write("Insert row ID: ");
string id = Console.ReadLine();
// TODO: You might want to add a condition here to allow the user to end loop.
// For example, if the user enters "quit" or an empty string "".
int rowValue;
Console.Write("Insert row value: ");
int.TryParse(Console.ReadLine(), out rowValue);
// TODO: what it TryParse fails?
// If this new data goes over the limit, exit loop
total += rowValue;
if (total > maxTotal) {
break;
}
// Add the new data
rows.Add(new Row(id, rowValue));
}
If you don't know how many times a loop needs to execute you use a while() { } loop structure. And inside the loop, you need to do four things
Accept user input
Check if the user input terminates the loop and issue a break; statement
Parse the input into data
Add the data to a list/collection.
Then outside the loop, you can do the processing you want (summing totals etc).
You have most of the pieces of the above together already, you just missing the actual loop and to arrange them in the order shown above.

Can someone please explain why does a piece of code work the same as mine?

I completed an exercise and wrote this code:
var random = new Random();
var number = random.Next(1, 10);
Console.WriteLine(number);
var control = 0;
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Enter a number: ");
var guessedNumber = Convert.ToInt32(Console.ReadLine());
if (guessedNumber == number)
{
Console.WriteLine("You won");
control = 1;
break;
}
}
if (control == 0)
{
Console.WriteLine("You lost");
}
And the answer is this:
var number = new Random().Next(1, 10);
Console.WriteLine("Secret is " + number);
for (var i = 0; i < 4; i++)
{
Console.Write("Guess the secret number: ");
var guess = Convert.ToInt32(Console.ReadLine());
if (guess == number)
{
Console.WriteLine("You won!");
return;
}
}
Console.WriteLine("You lost!");
I have added the control variable because if I didn't even if the user guessed the number it would still display "You lost".
Can someone explain what does "return" do in the other code and why if the user guesses the correct number it doesn't display "You lost"?
The Code is as I suppose packed in a function or main.
This function has a return type.
The function here maybe looks like this:
public void NumberGuessing()
{
.... code here ....
}
With the return statement you jump directly out of this block.
As the return type of the function is void, there is no value and a simple return will jump out of the function and everything after the return statement is not executed.
The break just exits the loop, but not the function.
your function is supposed to stop when you find the correct answer so return seems more logical, it eliminates the need for your extra control variable making the code simpler to read and less error prone (e.g. for changes in the future like find two correct answers).

Why I can't able to get the User Input for The List Items through the Console Window?

I'm new to Programming. Now I have to learn C# List Items.
My Expectation:
Create an Empty List
Get the Input value for this list from the user through the console
Window.
My Program:
using System;
using System.Collections.Generic;
namespace Indexof_in_List
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Implementation of IndexOf Method with List");
Console.WriteLine();
//If the user entered empty value or nothing in the console window, the window will exit automatically
//Create an Empty List
List<int> name = new List<int>();
Console.WriteLine("Enter the Input values for the List");
//Get the Inputs for the List from the Console Window
for (int n = 0; n < name.Count; n++)
{
bool check;
string input = Console.ReadLine();
check = int.TryParse(input, out int val);
if (check)
{
name[n] = val;
}
else
{
Environment.Exit(0);
}
}
//Implement Index of any number in the list items which you have entered to the console
Console.WriteLine("The Index of value 10 is = {0}",name.IndexOf(10));
Console.WriteLine();
Console.WriteLine("The Index of value 1000 is ={0}", name.IndexOf(1000));
Console.WriteLine();
Console.ReadKey();
}
}
}
Output:
Could Anyone Tell me the solution for this C# Logic? And also tell me the reason for this failure?
And Tell me, whether my Logic is correct or not?
Your code has a few issues:
Count retrieves the current number of items in your list.
You have created your list using the default constructor, so the Capacity is also 0. Because of this you can't loop from 0 to name.Capacity.
You are trying to add items using an index. You can only access existing items using the name[index] syntax.
The simplest solution is to initialize the list as you are, and simply add items:
List<int> name = new List<int>();
for (int i = 0; i < 10; ++i)
{
bool check;
string input = Console.ReadLine();
check = int.TryParse(input, out int val);
if (check)
{
name.Add(val);
}
else
{
Environment.Exit(0);
}
}
This will read 10 numbers one after the other and add them to the list.
Thank you for your valuable Comments. Finally, I have done the final changes based on your feedback.
My Code:
using System;
using System.Collections.Generic;
namespace Indexof_in_List
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Implementation of IndexOf Method with List");
Console.WriteLine();
//Create an Empty List
List<int> name = new List<int>();
//If the user entered empty value or nothing in the console window, the window will exit automatically
Console.WriteLine("Enter the Input values for the List");
//Get the Inputs for the List from the Console Window
for (int n=0;n<5;n++)
{
bool check=false;
string input = Console.ReadLine();
check = int.TryParse(input, out int val);
if (check)
{
name.Add(val) ;
}
else
{
Environment.Exit(0);
}
}
if (name.Count != 0)
{
//Implement Index of any number in the list items which you have entered to the console
int index1 = name.IndexOf(10);
Console.WriteLine("The Index of value 10 is = {0}", name.IndexOf(10));
if (index1!=-1)
{
Console.WriteLine("The number 10 found in the List");
}
else
{
Console.WriteLine("The Number 10 found in the List");
}
int index2 = name.IndexOf(1000);
Console.WriteLine("The Index of value 1000 is ={0}", name.IndexOf(1000));
if (index2 != -1)
{
Console.WriteLine("The number 1000 found in the List");
}
else
{
Console.WriteLine("The Number 1000 not found in the List");
}
Console.WriteLine();
}
Console.ReadKey();
}
}
}

c# input only using slot 0

I'm trying to get a user to input 1 value into the array, and then exit to main menu, then the next person to enter a value gets his put into the next bracket, not replace slot 0, currently it just loops the first array bracket and replaces the number. Help would be much appreciated
static void Main(string[] args)
{
int[] myArray = new int[10];
while (true)
{
int enteredNumber;
Startmenu();
enteredNumber = Convert.ToInt32(Console.ReadLine());
if (enteredNumber == 1)
{
for (int i = 0; i < myArray.Length; i++)
{
Console.WriteLine("Insert Number:");
myArray[i] = Convert.ToInt32(Console.ReadLine());
}
Console.Clear();
Console.WriteLine("blabla");
Thread.Sleep(2000);
Console.Clear();
}
if (enteredNumber == 9)
{
if (Login(1234, 3) == true)
{
foreach (int number in myArray)
{
Console.WriteLine(number);
}
}
}
}
}
One problem I think you have in that code is that you're trying to do too much in one method. You might want to break out discreet operations into separate methods, which will both enable code reuse and also serve to make your code more readable.
First, you need a method that will get an int from the user. Let's write a helper method that does that, which takes in a string that will be displayed as a prompt to the user, and which will continue to prompt them until they enter a valid int. We can use int.TryParse to determine if they enter a valie int. It takes a string argument to parse, and an out int that will contain the parsed value if it succeeds. The method itself returns true if it was successful:
private static int GetIntFromUser(string prompt)
{
int result;
do
{
Console.Write(prompt);
} while (!int.TryParse(Console.ReadLine(), out result));
return result;
}
You don't show the code for ShowMenu, but it probably gives the user some menu choices, and I've added the functionality where it returns the menu choice entered by the user:
private static int ShowMenu()
{
int menuChoice;
do
{
Console.Clear();
Console.WriteLine("Main Menu:");
Console.WriteLine("1. Input an array item");
Console.WriteLine("9. Print the numbers\n");
menuChoice = GetIntFromUser("Enter your choice (1 or 9): ");
} while (menuChoice != 1 && menuChoice != 9);
return menuChoice;
}
Now, another thing you seem to be missing that might help here, is to add a "pause" to the program after printing out the array items, so the user has a chance to see them. I think this is probably the main problem. Currently you write them all out to the screen, then the while loop runs again and you don't get a chance to see it. Here's a helper method that asks the user to press a key when they're ready, and then waits for the user to press a key:
private static void WaitForUserInput()
{
Console.Write("\nPress any key to continue...");
Console.ReadKey();
}
We can also put the code to populate the array in a separate method. Since you want to enable the user to populate only one item at a time, we will need to keep track of which item is the next one to populate, so we'll set a class-level variable for that, and make use of it in the method. We'll populate that item, then increment the variable. Of course we have to first make sure the next item is not greater than the number of items available:
private static int NextIndexToPopulate = 0;
private static void PopulateNextArrayItem(int[] array)
{
if (array == null) return;
if (NextIndexToPopulate >= array.Length)
{
Console.WriteLine("The array is full; no items left to enter.");
WaitForUserInput();
}
else
{
array[NextIndexToPopulate] = GetIntFromUser("Enter number to insert: ");
NextIndexToPopulate++;
}
}
And another method can be used to print out the array:
private static void PrintArray(int[] array)
{
if (array == null)
{
Console.WriteLine("The array is null - nothing to print.");
}
else
{
Console.WriteLine("Here are the array items entered:");
for (int i = 0; i < NextIndexToPopulate; i++)
{
Console.WriteLine(array[i]);
}
}
}
You also didn't show the Login code, so here's a dummy method I'll use that always returns true:
private static bool Login(int first, int second)
{
return true;
}
Now, with all that extra stuff encapsulated in methods, our main code becomes a little more readable, there's less chance for errors, and when there are errors, it's more clear what they are:
private static void Main()
{
int[] myArray = new int[10];
while (true)
{
int enteredNumber = ShowMenu();
if (enteredNumber == 1)
{
PopulateNextArrayItem(myArray);
}
else if (enteredNumber == 9)
{
if (Login(1234, 3))
{
PrintArray(myArray);
WaitForUserInput();
}
}
}
}

Creating a loop in my guessing game

How do I repeat this code/game if the player gets the answer wrong?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Random RandomGenerator = new Random();// random number generator
Console.WriteLine("i have thought of a number between 1 and 100");//display message
//
//
int IN_RandomNum = RandomGenerator.Next(1, 100); //the range
//loop 10 times
for (int i = 0; i < 10; i++) //for loop created
{
int IN_Guess; //guessing integer
Console.Write("{0} turns left, enter your next guess>", 10 - i);//number of turns players has
//
IN_Guess = Convert.ToInt32(Console.ReadLine()); //string to number
//Now check if guess is same as generated
if (IN_Guess == IN_RandomNum)//if guess is equal to generated number
{
Console.WriteLine("correct in {0} turns", i + 1); //if guessed correctly
break; //breaking code
}
else if (IN_Guess > IN_RandomNum) //if guess is higher than generated number
{
Console.WriteLine("Too high");// if guessed number is too high
}
else //then...
{
Console.WriteLine("Too low"); // if guessed number is too low
} if (i==8) //on last turn display this message
{
Console.WriteLine("*YOU ONLY HAVE 1 GUESS LEFT!*"); //display this message
}
}
Console.WriteLine("please press enter to quit"); //display message
Console.ReadLine();//keeps application open until enter button hit
}
}
}
Please help because i really cant figure out where to put the while loop...ive ran out of ideas
You would need to wrap everything in a while loop.
When it exits the for loop you have, it doesn't matter if they win or lose you go back to the top and start again, generating a new random number.
Before reading the code below, see my suggestion above and attempt it yourself, see if you can crack it
Something like this:
static void Main(string[] args)
{
Random RandomGenerator = new Random();// random number generator
while (true)
{
Console.WriteLine("i have thought of a number between 1 and 100");//display message
bool guessedCorrect = false;
int IN_RandomNum = RandomGenerator.Next(1, 100); //the range
//loop 10 times
for (int i = 0; i < 10; i++) //for loop created
{
int IN_Guess; //guessing integer
Console.Write("{0} turns left, enter your next guess>", 10 - i);//number of turns players has
//
IN_Guess = Convert.ToInt32(Console.ReadLine()); //string to number
//Now check if guess is same as generated
if (IN_Guess == IN_RandomNum)//if guess is equal to generated number
{
Console.WriteLine("correct in {0} turns", i + 1); //if guessed correctly
guessedCorrect = true;
break; //breaking code
}
else if (IN_Guess > IN_RandomNum) //if guess is higher than generated number
{
Console.WriteLine("Too high");// if guessed number is too high
}
else //then...
{
Console.WriteLine("Too low"); // if guessed number is too low
}
if (i == 8) //on last turn display this message
{
Console.WriteLine("*YOU ONLY HAVE 1 GUESS LEFT!*"); //display this message
}
}
if (guessedCorrect)
{
Console.WriteLine("Good job... Lets try again");
}
else
{
Console.WriteLine("Better luck next timer... here we go");
}
}
}
P.S. I lost every time i tried, your game is too hard :-(

Categories

Resources