namespace C2360_Ch07_Console1_InRange
{
class InRange
{
static void Main(string[] args)
{
Console.WriteLine("Num:");
String theLine;
theLine = Console.ReadLine();
try
{
theLine = Convert.ToInt32(Console.ReadLine());//cant convert
}
catch (FormatException)
{
Console.WriteLine("Input string was not in a correct format.");
}
IsWithinRange(theLine);
}
static void IsWithinRange(String theLine)
{
int Line1;
Int32.TryParse(Console.ReadLine(), out Line1);
try
{
if ((Line1 < 1) || (Line1 > 10))
{
throw new OverflowException();
}
}
catch (OverflowException)
{
Console.WriteLine("number must be between 1 and 10.");
}
Console.ReadLine();
}
}
}
What im trying to do is to convert string to integer to validate Main and IsWithinRange method. I get an error, where the comment is at, when I convert theLine to Int32.TryParse. Is this ever possible?
Anything would help?
I suggest extracting a method for reading integer value:
private static int ReadInteger(string title) {
while (true) {
Console.WriteLine(title);
if (int.TryParse(Console.ReadLine(), out int result))
return result;
Console.WriteLine("Incorrect syntax. Please, try again");
}
}
And then use it:
static void Main(string[] args) {
int theLine = 0;
while (true) {
theLine = ReadInteger("Num:");
// theLine is an integer, but we want an extra conditions meet:
if (theLine >= 1 && theLine <= 10)
break;
Console.WriteLine("The value must be in [1..10] range. Please, try again");
}
// from now on theLine is an integer in [1..10] range
//TODO: put relevant code here
}
Please, note, that exceptions FormatException, OverflowException are for exceptional behavior; here (user input validation), good old if is enough.
Edit: If you don't want to extract method (why?) but preserve IsWithinRange you can put something like this:
static void Main(string[] args) {
int theLine = 0;
while (true) {
Console.WriteLine("Num:");
if (!int.TryParse(Console.ReadLine(), out theLine)) {
Console.WriteLine("Syntax error. Please, try again");
continue;
}
if (IsWithinRange(theLine))
break;
Console.WriteLine("Sorry, the value is out of range. Please, try again");
}
// from now on theLine is an integer in [1..10] range
//TODO: put relevant code here
Where IsWithinRange can be
// Least Confusion Principle: For "Is [the value] Within Range" question
// the expected answer is either true or false
private static bool IsWithinRange(int value) {
return value >= 1 && value <= 10;
}
Related
I'm having issues creating a program that is a number guessing program. I think I have the written part right but possibly not the order of it? I have to use multiple methods such as a method for number generator of the number that is supposed to be guessed, a method for collecting the guess input, and method for checking the guess to see if it's right. I've literally have tried just about everything for days but all I get is rather a repeat of, "Enter the number: " even if its right, although it's supposed to repeat if it's too high or low. Or sometimes the console won't print anything. what is wrong? Here is the code:
using System;
namespace GuessTheNumber
{
class Program
{
public static int RandomNumberGenerator()
{
Random random = new Random();
return random.Next(1, 21);
}
public static int InputGetter()
{
Console.Write("Enter in a number: ");
int guess = Convert.ToInt32(Console.ReadLine());
return guess;
}
public static String GuessChecker(int guess, int secretNumber)
{
if(guess > secretNumber)
{
return "Too high!";
}
else if (guess < secretNumber)
{
return "Too low!";
}
else
{
return "Correct";
}
}
static void Main(string[] args)
{
int secretNumber = 10;
Console.WriteLine("" + secretNumber);
while (true)
{
while (InputGetter() != secretNumber)
{
InputGetter();
GuessChecker(InputGetter(), secretNumber);
}
if (GuessChecker(InputGetter(), secretNumber) == ("Correct!"))
{
Console.WriteLine("Would you like to play again?");
String input = Console.ReadLine();
if (GuessChecker(InputGetter(), secretNumber) == ("Yes"))
{
secretNumber = RandomNumberGenerator();
}
else if (GuessChecker(InputGetter(), secretNumber) == ("No"))
{
break;
}
}
}
}
}
}
You are invoking InputGetter() multiple times and your logic is incorrect.
It has nothing to do with Random instance being used.
I have quickly modified your code and it should work now as follows:
New number is generated, if you enter low/high message is displayed, if you enter correct number you are presented with the Would you like to try again message.
EDIT: I did not want to change original code much,In general Comparing strings is bad, you should not use it. Creating enum like and comparing would be much better
class Program
{
public static int RandomNumberGenerator()
{
Random random = new Random();
var generatedNumber = random.Next(1, 21);
Console.WriteLine($"New Number generated! {generatedNumber}");
return generatedNumber;
}
public static int InputGetter()
{
Console.Write("Enter in a number: ");
int guess = Convert.ToInt32(Console.ReadLine());
return guess;
}
public static String GuessChecker(int guess, int secretNumber)
{
if (guess > secretNumber)
{
Console.WriteLine("Too High");
return "Too high!";
}
else if (guess < secretNumber)
{
Console.WriteLine("Too low!");
return "Too low!";
}
else
{
Console.WriteLine("Correct");
return "Correct";
}
}
static void Main(string[] args)
{
int secretNumber = 10;
Console.WriteLine("" + secretNumber);
while (true)
{
int enteredNumber = 0;
do
{
enteredNumber = InputGetter();
} while (GuessChecker(enteredNumber, secretNumber)!="Correct");
Console.WriteLine("Would you like to play again?[Yes/No]");
String input = Console.ReadLine();
if (input=="Yes")
{
secretNumber = RandomNumberGenerator();
}
else
{
break;
}
}
}
}
First of all, I am a complete newbie at programming and c#..so here is my dilemma.
The user should only enter a number, entering anything else should fail and repeat the question.
I have been using try catch but, as soon as the error gets thrown the user doesn't have a second chance to enter a number again, I just get an error and the ConsoleApp Closes.
This is my code atm
static public int AskInt(string question)
{
try
{
Console.Write(question);
return int.Parse(Console.ReadLine());
}
catch (Exception)
{
throw new FormatException("Please Enter a Number");
}
}
Thank you in advance.
static public int AskInt(string question)
{
int answer = 0;
bool successfullyParsed = false;
do
{
Console.Write(question);
successfullyParsed = int.TryParse(Console.ReadLine(), out var parsedAnswer);
if(!successfullyParsed){
Console.WriteLine("Only Numbers, dude");
}
answer = parsedAnswer;
} while (!successfullyParsed);
return answer;
}
Explaining a bit. TryParse will return a boolean indicating the success of the operation and an out variable with the result.
I can't return the parsedAnswer because it is in the context of the do loop.
You can make this code less legible but short. I tried to make it this why to be kinda of self explanatory.
Use below code which uses TryParse of int to parse the entered string. If TryParse succeed then it will break the while loop.
public static int AskInt(string question)
{
int questionId;
while (true)
{
Console.Write(question);
string input = Console.ReadLine();
if (int.TryParse(input , out questionId))
{
break;
}
}
}
int i=1;
while(i==1)
{
try {
Console.WriteLine("your question");
int number= int.Parse(Console.ReadLine());
i=0;
}
catch (Exception)
{
i=1;
Console.WriteLine("Please Enter a Number");
}
}
static public int AskInt(string question)
{
for (;;)
{
Console.Write(question);
if (int.TryParse(Console.ReadLine(), out int result))
{
return result;
}
}
}
This code currently handles inputs of numbers just fine whether greater or less or within the accepted range, however, the program crashes when anything that isn't a number is entered with an unhandled exception error.System.FormatException: 'Input string was not in a correct format.' That's the error if that helps at all.
using System;
class Program
{
static void PrintHello(int NumberOfTimes)
{
if (NumberOfTimes > 1 && NumberOfTimes < 11)
{
for (int Counter = 0; Counter < NumberOfTimes; Counter++)
{
Console.WriteLine("Hello.");
}
}
else { Console.WriteLine("Error, please enter a number between 1 and 10"); }
}
static void Main(string[] args)
{
int myNumber = 1;
while (myNumber != 0)
{
Console.WriteLine("Enter a number between 1 and 10, or 0 to stop");
myNumber = Convert.ToInt16(Console.ReadLine());
PrintHello(myNumber);
}
}
}
Just replace your Convert.ToInt16(...) with the following:
var input = Console.ReadLine();
if (int.TryParse(input, out myNumber))
{
PrintHello(myNumber);
}
The int.TryParse-method will return true, if the given input can be parsed as an integer, otherwise false. If it could parse the input, the value will be stored in the second parameter (which is flagged as out.
Edit:
As a rule of thumb: Never parse user-input directly (especially when you are handling with strings as input). Check if the input is valid.
You can use try and catch when parsing the input string as shown here:
try
{
int NumberOfTimes = int.Parse(Console.ReadLine());
}
catch(System.FormatException)
{
Console.WriteLine("Incorrect format of the user's input");
}
I wrote this little program that catches five integer numbers that are entered consecutively at the console.
This works as expected - except for one thing:
I did not find a way to accept 0 as one of the numbers being entered.
Of course, a solution with another collection type is easy.
But the challenge here is to do it with an array of five integers.
I tried to set a boolean flag "zeroEntered", tried with a counter, tried to count j backwwards. It all does not work.
Perhaps this is not possible? Would somebody know for sure?
Here is the code:
class Program
{
static void Main(string[] args)
{
#region Catch5IntegerInArrayOfInt[5]
// I try to catch five integers in an array of int[5]
// This works as expected except I cannot catch 0 as one of the numbers
// Cannot wrap my head around this one it seems
// because all ints are initialized with 0
Console.WriteLine("Please enter five unique numbers consecutively.");
int[] fiveNumbers = new int[5]; // do it using an array just the same (as collections were not part of the lectures so far)
for (int i = 0; i < fiveNumbers.Length; i++)
{
Console.WriteLine("Please enter your {0} number:", (Countables)i);
CatchUsersNumbers(fiveNumbers, i);
}
DisplayResult(fiveNumbers);
Console.WriteLine("\n");
}
#endregion
#region HelperMethods
private static bool CheckWhetherInteger(string userInput)
{
bool result = Int32.TryParse(userInput, out myInteger);
if (result == false)
{
Console.Clear();
Console.WriteLine("You did not enter an integer.");
}
return result;
}
private static bool CheckUniqueness(int[] fiveNumbers, int userInput)
{
for (int i = 0; i < fiveNumbers.Length; i++)
{
if (userInput == 0)
{
for (int j = i ; j <fiveNumbers.Length; j--)
{
if (j == 0)
break;
if (fiveNumbers[j] == 0)
{
return false;
}
}
}
else if (fiveNumbers[i] == userInput)
{
return false;
}
}
return true;
}
private static void CatchUsersNumbers(int[] fiveNumbers, int i)
{
while (true)
{
userInput = Console.ReadLine().Trim();
if (CheckWhetherInteger(userInput) && CheckUniqueness(fiveNumbers, myInteger))
{
fiveNumbers[i] = myInteger;
break;
}
else
Console.Clear();
Console.WriteLine("You did not enter a unique integer number, try again...");
}
}
private static void DisplayResult(int[] fiveNumbers)
{
Console.Clear();
Array.Sort(fiveNumbers);
Console.WriteLine("These are the five interger numbers you entered \nand that were stored in the array:\n");
for (int i = 0; i < fiveNumbers.Length; i++)
{
if (i != fiveNumbers.Length - 1)
Console.Write(fiveNumbers[i] + ", ");
else
Console.Write(fiveNumbers[i]);
}
}
#endregion
#region Class Variables
private static int myInteger = 0;
private static string userInput;
private enum Countables
{
first = 0,
second,
third,
fourth,
fifth
}
#endregion
}
Thank you.
It is possible, but your array of 5 ints will be initialized to 5 zeroes, so when scanning for uniqueness, your check fails, especially because of this piece of code:
if (fiveNumbers[j] == 0)
{
return false;
}
So instead of looping through the entire array, you should keep a counter to keep track of how many items you already have in your array. Then, when performing the check, only check upto that index, and don't include the other items in the check, because they contain 0, but you should treat them as uninitialized.
You could also solve this using other data types. For instance, you could create an array of nullable integers, so you can actually check whether an item already got a value. Or (maybe the best solution) you could use a List instead of array.
Your Only error here is that int.TryParse() takes 0 as invalid you could make another if statement to handle the exception but this looks less clean
private static bool CheckWhetherInteger(string userInput)
{
if (userInput == "0")
{
myInteger = 0;
return true
}
else
{
bool result = Int32.TryParse(userInput, out myInteger);
if (result == false)
{
Console.Clear();
Console.WriteLine("You did not enter an integer.");
}
}
return result;
}
I just post the solution - using nullable integers - as suggested by Golez Trol. Here it is, should somebody be interested:
class Program
{
static void Main(string[] args)
{
#region Catch5IntegerInArrayOfInt[5]
// The solution to catching five integers in an array of int[5]
// is to use nullable integers.
// Keeping a counter when entering an integer to the array does not appeal to me.
// With normal integers I cannot catch 0 as one of the numbers
// because all ints are initialized with 0
Console.WriteLine("Please enter five unique numbers consecutively.");
var fiveNumbers = new int?[5]; // do it using an array just the same (as collections were not part of the lectures so far)
for (int i = 0; i < fiveNumbers.Length; i++)
{
Console.WriteLine("Please enter your {0} number:", (Countables)i);
CatchUsersNumbers(fiveNumbers, i);
}
DisplayResult(fiveNumbers);
Console.WriteLine("\n");
}
#endregion
#region HelperMethods
private static void CatchUsersNumbers(int?[] fiveNumbers, int i)
{
while (true)
{
userInput = Console.ReadLine().Trim();
if (CheckWhetherInteger(userInput) && CheckUniqueness(fiveNumbers, myInteger))
{
fiveNumbers[i] = myInteger;
break;
}
else
{
Console.Clear();
Console.WriteLine("You did not enter a unique integer number, try again...");
}
}
}
private static bool CheckWhetherInteger(string userInput)
{
bool result = Int32.TryParse(userInput, out myInteger);
if (result == false)
{
Console.Clear();
Console.WriteLine("You did not enter an integer.");
}
return result;
}
private static bool CheckUniqueness(int?[] fiveNumbers, int userInput)
{
for (int i = 0; i < fiveNumbers.Length; i++)
{
if (fiveNumbers[i] == userInput)
{
return false;
}
}
return true;
}
private static void DisplayResult(int?[] fiveNumbers)
{
Console.Clear();
Array.Sort(fiveNumbers);
Console.WriteLine("These are the five interger numbers you entered \nand that were stored in the array:\n");
for (int i = 0; i < fiveNumbers.Length; i++)
{
if (i != fiveNumbers.Length - 1)
Console.Write(fiveNumbers[i] + ", ");
else
Console.Write(fiveNumbers[i]);
}
}
#endregion
#region Class Variables
private static int myInteger = 0;
private static string userInput;
private enum Countables
{
first = 0,
second,
third,
fourth,
fifth
}
#endregion
}
Thank you for your hints - I was truly stuck.
Hey guys this is what i got so far:
static string ConvertToInt()
{
string a = Console.ReadLine();
int num = int.Parse(a);
Console.WriteLine(num);
if (int.TryParse(a, out num))
{
return a;
}
else
{
return "-1";
}
}
What I'm trying to do is to write a custom Convert.ToInt function without actually using the method which is already available in the library. So I tried using int.Parse. It's also supposed to return -1 if the input by the user is NOT a number.
My problem here is that the application simply stops when debugging if I enter "a" and gives me the error that the input string is not in the correct format.
When testing the method, I created a new project with these modifications:
static void Main(string[] args)
{
string a = Console.ReadLine();
int num = int.Parse(a);
Console.WriteLine(num);
if (int.TryParse(a, out num))
{
Console.WriteLine(a);
}
else
{
Console.WriteLine("-1");
}
}
Thanks in advance.
remove the first Parse and leave it as int num;
static void Main(string[] args)
{
string a = Console.ReadLine();
int num;
if (int.TryParse(a, out num))
{
Console.WriteLine(a);
}
else
{
Console.WriteLine("-1");
}
}
Problem : int.Parse() throws FormatException when string is not in correct format.
Solution: remove the int.Parse() function and don't assign value to num variable
Try This:
string a = Console.ReadLine();
int num;
if (int.TryParse(a, out num))
{
Console.WriteLine(a);
}
else
{
Console.WriteLine("-1");
}