How do I Limit C# ReadKey entries? - c#

I've been trying to find a way to do this but not had much luck so far.
Basically what I'm trying to do is limit the entries from the user so they can only enter 1 letter and 1 number using the Console.Readkey. So, for example, A1, E5, J9 etc. I want to avoid them entering like 55 or EE as this causes an error in my code. Is there an easy way to achieve this?

You need to write your own logic like you will check on every input value contains at least 1 number and 1 letter is true else false:
string value = Console.ReadLine();
//you can also check value.length and redirect if length greater than 2
if (value.Length > 2)
{
Console.WriteLine("Please enter correct value");
return;
}
if (value.Contains("Your Number"))
{
if (value.Contains("Your Letter"))
{
//your code goes here
}
else
{
Console.WriteLine("Please Enter Correct Value");
}
}
else
{
Console.WriteLine("Please Enter Correct Value");
}

This uses a GetChar method which requires that you pass a function to check whether the input is a character or a number. It won't allow you so proceed until a valid entry has been made.
using System;
class Program {
public static void Main (string[] args) {
string value = string.Empty;
// Get a character, using char.IsLetter as the checking function...
GetChar(ref value, char.IsLetter);
// Get a number, using char.isNumber as the checking function...
GetChar(ref value, char.IsNumber);
Console.WriteLine($"\nValue: {value.ToUpper()}");
}
// Get a character and append it to the referenced string.
// check requires that you pass a function reference for the required check.
public static void GetChar(ref string value, Func<char, bool> check) {
// Loop until the check passes.
while(true) {
char key = Console.ReadKey(true).KeyChar;
// If check passes...
if(check(key)) {
// Append the value
value += key.ToString().ToUpper();
// Print it...
Console.Write(key.ToString().ToUpper());
// Break out of the loop.
break;
}
}
}
}

Related

Why does the error message not show for the first try, but works fine for the other?

Can someone please tell me why the first try catch is not showing an error message when the user inputs invalid format of data, i.e inputs integar instead of string. If I input numbers instead of letters, the program just accepts it and moves forward.
The other try catch for age is working fine.
public void add_passenger()
{
// Defining variables for name and age to be input
string name;
int age;
//Show message on a clean, new screen
Console.Clear();
Console.WriteLine("==> Welcome aboard <==");
Console.WriteLine(" Please follow instructions to add yourself as a passenger ");
Console.WriteLine("");
// Ask user to input name
while (true)
{
Console.WriteLine(" Your name: ");
//Try and catch in case the user inputs wrong format
try
{
name = Console.ReadLine();
break;
}
catch //This doesn't work
{
Console.WriteLine(" Wrong input format. Please try again and input a rider.");
continue;
}
}
// Ask user to input age
while (true)
{
Console.WriteLine(" Your age: ");
//Try and catch in case the user inputs wrong format
try
{
age = Convert.ToInt32(Console.ReadLine());
break;
}
catch
{
Console.WriteLine(" Wrong input format. Please write an integer.");
continue;
}
}
// Search the array for an empty slot to input the new passenger into
for (int i = 0; i < passengers.Length - 1; i++)
{
if (passengers[i] == null)
{
passengers[i] = new Passagerare(name, age);
break;
}
else
{
continue;
}
}
Console.WriteLine("");
Console.WriteLine(" You have now boarded the bus. Welcome aboard!" );
Console.ReadKey(true);
}
The first try/catch block is working properly as well. It's up to you, the developer to determine what value a string can contain in order for it to be valid or invalid.
In terms of the language, both "john doe" and "123151" are valid strings (the second one is just a string representation of digits). Keep in mind that the code interprets these two very differently:
"123151"
123151
The first is a string with the value "123151".
The second is an integer with the value 123151.
When you read from the console.ReadLine() function into a string variable, you will get a string value of whatever value is input.
What I would suggest, moving forward, is that you add some sort of programming to verify that the value that is input is more like the value your program is expecting. For example, if you're not expecting the string to have any numbers in it, you could check the string for integer values, and throw the exception if any are found. You might even use Regular Expressions to help identify integers or other invalid values.

Do loop practice?

static void Main(string[] args)
{
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)
{
while (number <= output)
{
switch (conversion)
{
case true:
Console.Write(number + " ");
number += 2;
break;
case false:
Console.WriteLine("ERROR INVALID INPUT!");
break;
}
}
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
}
string choice = Console.ReadLine();
do // Here is the beginning of the do code
{
Console.WriteLine("Do you want to continue - Yes or No");
if(choice.ToUpper() != "NO" && choice.ToUpper() != "NO");
{
Console.WriteLine("ERROR INVALID INPUT: Only input Yes or No!");
}
}while(choice.ToUpper() != "YES" && choice.ToUpper() != "NO");
}
}
}
This is a very simple application and is unfinished but what it does is you put in a number below or equal to 1000 and it counts up to it evenly. My only problem is with the do statement at the end of the code. Its unfinished but from what I've researched that do statement is completed what happens is if the user does not input yes or no it will show them that error and then ask again "do you want to go again" However because of this do statement I put in any number like 10 and it gives me the error saying its over 1000 and then goes on an infinite loop of saying "ERROR INVALID INPUT: ONLY INPUT YES OR NO!" How can I fix this?
Your if statement tests for NOT EQUAL to "no" twice, I assume you mean to check for not equal to "YES" and not equal to "NO"
Your infinite loop is because the condition checks the content of choice, but you never change the value of the variable within the do loop - only in the Console.ReadLine() immediately before the loop starts.
You should start the do loop before the code you want to be repeated. For instance, if your intent is that if the user types yes that the entire process repeats, you may be best served by creating a void function, say static void CountNumbers() { ... } that has all the code doing your input on how high to count, error handling, etc. Then you can use your do loop to easily repeat as much as the user wants, like this:
string choice = null;
do
{
CountNumbers();
// Your code here to ask if user wants to continue and readline to get the new choice
} while ( /* Existing condition */);
You have several issues in the code:
First, your condition checks that number is GREATER than or equal to 1000. Since you're entering 10, which is not >= 1000, then you get to the else statement. So you need to change your condition to:
if(number <= 1000)
Next, your condition in the do loop checks the same condition twice... you don't allow the user to enter "yes". You should modifiy the condition to include a check for "yes". Also, you need to remove the semi-colon from the end of that same if statement:
do
{
Console.WriteLine("Do you want to continue - Yes or No");
choice = Console.ReadLine();
if(choice.ToUpper() != "NO" && choice.ToUpper() != "NO");
{
Console.WriteLine("ERROR INVALID INPUT: Only input Yes or No!");
}
} while(choice.ToUpper() != "YES" && choice.ToUpper() != "NO");
One thing you also might consider is adding a method to get an integer from the user, since it is handy to wrap it in some validation:
public static int GetIntFromUser(string prompt,
string errorMessage = "Invalid entry. Please try again.")
{
int value;
while (true)
{
if (prompt != null) Console.Write(prompt);
if (int.TryParse(Console.ReadLine(), out value)) break;
if (errorMessage != null) Console.WriteLine(errorMessage);
}
return value;
}
Then, you can call this method when you need to get an int from the user. Here's a sample of how it could be used:
private static void GenericTester()
{
// This will flag that the user wants to quit
bool quit = false;
while(!quit)
{
// Get input from user
int userInput = GetIntFromUser("Please input a number to be counted: ");
int number = 0;
// Write out the numbers
if (userInput <= 1000)
{
while (number <= userInput)
{
Console.Write(number + " ");
number += 2;
}
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW " +
"OR AT 1000 TO PREVENT OVERFLOW!");
}
// See if they want to continue
while (true)
{
// Get user input
Console.Write("Do you want to continue - Yes or No: ");
string choice = Console.ReadLine();
// If they said 'No', set flag to quit and break out of this loop
if (choice.Equals("No", StringComparison.OrdinalIgnoreCase))
{
quit = true;
break;
}
// If they said 'Yes', just break out of this loop
if (choice.Equals("Yes", StringComparison.OrdinalIgnoreCase)) break;
// Otherwise, display an error message and let the loop continue
Console.WriteLine("ERROR INVALID INPUT: Only input Yes or No!");
}
}
}

not all code paths return a value? help needed

I am making a c# console board game and I am having trouble trying to sort out this error that is currently linked to the static int ResetGame() part. Apparently not all code paths return a value. How do I fix this?
static int ResetGame()
{
Console.WriteLine("Welcome to Tactical Space Cheese Racer");
Console.WriteLine("");
Console.WriteLine("Press any Key to continue");
Console.ReadLine();
Console.Clear();
Console.WriteLine("Please enter the number of players that wish to play (2-4) : ");
int NoOfPlayers = int.Parse(Console.ReadLine());
Console.WriteLine("");
for (int i = 0; i < NoOfPlayers; i++)
{
Console.WriteLine("");
Console.WriteLine("Please enter the name of the player: " + i + i++);
Console.WriteLine("");
players[i].Name = Console.ReadLine();
players[i].Pos = 0;
}
}
I have more code available if you need to see it to resolve the problem
The problem you have is that your method should return an int and you don't return it.
If you don't want to return anything, then you should state that your method is a void method.
static void ResetGame()
{
}
As I can conclude from your code, this might was your intention. So making your method a void one, you will not have any problem.
Furthermore, I have to make a side note about the way you set the number of players. If the user enters a non integere value you will get an exception, that you don't handle. In addition to this, if the user enters an integer greater than 4, that shouldn't be ok. That being said you should take care both of the above.
int numberOfPlayers = -1;
Console.WriteLine("Please enter the number of players that wish to play (2-4) : ");
// The method Int32.TryParse parses the input and check if it
// can be represented as a 32-bit integer number.
// If parse succeeds, then the value is assigned to numberOfPlayers
// and the method returns true. Otherwise, it returns false.
while(!Int32.TryParse(Console.ReadLine()), out numberOfPlayers) &&
!(numberOfPlayers>2 && numberOfPlayers<4))
{
Console.WriteLine("Please enter a valid number between (2-4): ");
}
update
Idle_Mind pointed out in his comment the following:
I would say he needs to Return the Number of Players.
If that's the case, you just simple have to add this before the closing curly brace of your method:
return numberOfPlayers;
I suppose that you will keep my naming. If you will keep yours just change the name of the variable to yours.

C#- Getting user input for Age.. but receiving error?

I am trying to make improve my programming and getting things drilled into my head so I'm just quickly developing an application that gets user's input and prints their name. But also gets their input for "Age verification".
I'm practicing IF & ELSE statements as well as nesting classes.
However my compiler is shooting me an error and I just cannot seem to figure it out. I'm trying to get the user to input his age, and then proceed with the IF & ELSE statement.
Compiler is shooting error that . ""Cannot implicitly convert type
string to int"
The only error in the program right now is the
myCharacter.age = Console.ReadLine();
using System;
namespace csharptut
{
class CharPrintName
{
static void Main()
{
Character myCharacter = new Character();
Console.WriteLine("Please enter your name to continue: ");
myCharacter.name = Console.ReadLine();
Console.WriteLine("Hello {0}!", myCharacter.name);
Console.WriteLine("Please enter your age for verification purposes: ");
myCharacter.age = Console.ReadLine();
if (myCharacter.age <= 17)
{
Console.WriteLine("I'm sorry {0}, you're too young to enter!",myCharacter.name);
}
else if (myCharacter.age >= 18)
{
Console.WriteLine("You can enter!");
}
}
}
class Character
{
public string name;
public int age;
}
}
As the error says you can't implicitly type a string to an int. You need to parse it into an int.
string input = Console.ReadLine();
int age;
if (int.TryParse(input, out age)
{
// input is an int
myCharacter.age = age;
}
else
{
// input is not an int
}
You are trying to assign a string value to an int with this line:
myCharacter.age = Console.ReadLine();
Try:
myCharacter.age = Int32.Parse(Console.ReadLine());
character.age expects an Int but ReadLine() returns a string, you need to look at using int.Parse or int.TryParse to avoid exceptions
e.g.
if (!int.TryParse(Console.ReadLine(),out myCharacter.age)) {
Console.WriteLine("You didn't enter a number!!!");
} else if (myCharacter.age <= 17) {
Console.WriteLine("I'm sorry {0}, you're too young to enter!",myCharacter.name);
} else {
Console.WriteLine("You can enter!");
}
This looks like a student project.
The input coming from the ReadLine() is always of type string. You're then comparing a string to 17 which isn't valid, as 17 is an int. Use TryParse versus parse to avoid throwing an exception at runtime.
string typedAge = Console.ReadLine();
int Age = 0;
if (!int.TryParse(typedAge, out Age))
Console.WriteLine("Invalid age");
if (Age <= 17)
Console.WriteLine("You're awfully young.");
OK. The problem here is that the age is defined as an int and Console.ReadLine() always returns a string so thus you have to convert the user input from string to integer in order to correctly store the age.
Something like this:
myCharacter.age = Int32.Parse(Console.ReadLine());
When you read input from the console, it returns it to you in the form of a string. In C#, which is a statically typed language, you cannot simply take one type and apply it to another type. You need to convert it somehow, there are several ways to do this.
The first way would be casting:
myCharacter.age = (int)Console.ReadLine();
This won't work because a string and an integer are two completely different types and you can't simply cast one to the other. Do some reading on casting types for more information.
The second way would be to convert it, again there are a couple of ways to do this:
myCharacter.age = Int32.Parse(Console.ReadLine());
This will work as long as you type in an actual number, in this case the Parse method reads the string and figures out what the appropriate integer is for you. However, if you type in "ABC" instead, you will get an exception because the Parse method doesn't recognize that as an integer. So the better way would be to:
string newAge = Console.ReadLine();
int theAge;
bool success = Int32.TryParse(newAge, out theAge);
if(!success)
Console.WriteLine("Hey! That's not a number!");
else
myCharacter.age = theAge;
In this case the TryParse method tries to parse it, and instead of throwing an exception it tells you it can't parse it (via the return value) and allows you to handle that directly (rather than thru try/catch).
That's a little verbose, but you said you're learning so I thought I'd give you some stuff to consider and read up on.

Convert String to int in C#

I am trying to write a simple program that asks the user to enter a number and then I will use that number to decide what the cost of the ticket will be for their given age. I am having trouble when trying to convert the string to int. Otherwise the program layout is fine. Any suggestions?
thanks
using System;
class ticketPrice
{
public static void Main(String[] args)
{
Console.WriteLine("Please Enter Your Age");
int input = Console.ReadLine();
if (input < 5)
{
Console.WriteLine("You are "+input+" and the admisson is FREE!");
}
else if (input > 4 & input < 18)
{
Console.WriteLine("You are "+input+" and the admission is $5");
}
else if (input > 17 & input < 56)
{
Console.WriteLine("You are "+input+" and the admission is $10");
}
else if (input > 55)
{
Console.WriteLine("You are "+input+" and the admission is $8");
}
}
}
Try the int.TryParse(...) method. It doesn't throw an exception.
http://msdn.microsoft.com/en-us/library/f02979c7.aspx
Also, you should use && not & in your conditions. && is logical AND and & is bitwise AND.
For easy parsing of strings to integers (and other number types), use that number type's .TryParse(inputstring, yourintegervariable) method. This method will output a Boolean (True/False), letting you know whether the operation passed or failed. If the result is false, you can give an error message before going any further (don't have to worry about crashing your program).
Previous text concerning switch statements has been removed
In C#, you need to use the && operator for logical AND. & is not the same and may not work the way you believe it will.
I suggest to use the Int32.TryParse() method. Further I suggest to refactor your code - you can make it much cleaner (assuming this is not just example code). One solution is to use a key value pair list to map from age to admission.
using System;
using System.Collections.Generic;
using System.Linq;
static class TicketPrice
{
private static readonly IList<KeyValuePair<Int32, String>> AgeAdmissionMap =
new List<KeyValuePair<Int32, String>>
{
new KeyValuePair<Int32, String>(0, "FREE!"),
new KeyValuePair<Int32, String>(5, "$5."),
new KeyValuePair<Int32, String>(18, "$10."),
new KeyValuePair<Int32, String>(56, "$8.")
};
public static void Main(String[] args)
{
Console.WriteLine("Please Enter Your Age!");
UInt32 age;
while (!UInt32.TryParse(Console.ReadLine(), out age)) { }
String admission = TicketPrice.AgeAdmissionMap
.OrderByDescending(pair => pair.Key)
.First(pair => pair.Key <= age)
.Value;
Console.WriteLine(String.Format(
"You are {0} and the admission is {1}",
age,
admission));
}
}
I used an unsigned integer to prevent entering negative ages and put the input into a loop. This way the user can correct an invalid input.
int number = int.Parse(Console.ReadLine());
Be aware that this will throw an exception if they enter an invalid number.
The first thing you need to do is change your input variable to a string:
string input = Console.ReadLine();
Once you have that, there are several ways to convert it to an integer. See this answer for more info:
Better way to cast object to int

Categories

Resources