Brand new to C# [4 hours new :)], but hoping for some pointers on a Board Feet Calculator restricting the user input to only numbers, not allow letters or special characters.
First, does the restriction take place in the Class, Method, and/or Program? (I believe Class and Method)
Second, I've seen an example below, would I use something similar to this?
Third, if so, do I need to make separate classes for KeyPress and KeyPressEventArgs? (I believe they automatically there e.g.
public char KeyChar { get; set; }
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
// allows only letters
if (!char.IsLetter(e.KeyChar))
{
e.Handled = true;
}
}
My Program
namespace BoardFt_MyTry_
{
class Program
{
static void Main(string[] args)
{
Board board = new Board();
board.lengthOfboard = Convert.ToDouble(askQuestion("What is the length of your board in inches?"));
board.widthOfboard = Convert.ToDouble(askQuestion("What is the width of your board in inches?"));
board.thicknessOfboard = Convert.ToDouble(askQuestion("What is the thickness of your board in inches?"));
Console.WriteLine("Your board has {0} board feet.", board.CalcBoardFt());
Console.ReadLine();
}
private static string askQuestion(string question)
{
Console.WriteLine(question);
return Console.ReadLine();
}
}
My Board Class
namespace BoardFt_MyTry_
{
class Board
{
public double lengthOfboard;
public double widthOfboard;
public double thicknessOfboard;
public double CalcBoardFt()
{
double boardft = 0;
boardft = (this.lengthOfboard * this.widthOfboard * this.thicknessOfboard) / 144;
return boardft;
}
}
}
You can't really do that in a console application. All you can do is allow the user to input the bad data, then tell the user that the data is bad.
You can try something like this:
class Program
{
public double AskDnoubleQuestion(string message){
do {
Console.Write(message);
var input = Console.ReadLine();
if (String.IsNullOrEmpty(input)){
Console.WriteLine("Input is required");
continue;
}
double result;
if (!double.TryParse(input, out result)){
Console.WriteLine("Invalid input - must be a valid double");
continue;
}
return result;
}
static void Main(string[] args)
{
Board board = new Board();
board.lengthOfboard = AskDoubleQuestion("What is the length of your board in inches?");
board.widthOfboard = AskDoubleQuestion(askQuestion("What is the width of your board in inches?");
board.thicknessOfboard = AskDoubleQuestion(askQuestion("What is the thickness of your board in inches?");
Console.WriteLine("Your board has {0} board feet.", board.CalcBoardFt());
Console.ReadLine();
}
In case validation is not the way you want to proceed, you could do something like this:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a number:");
string number = ReadNumber();
Console.WriteLine("You entered: " + number);
}
private static string ReadNumber()
{
string input = "";
do
{
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
if (char.IsNumber(keyInfo.KeyChar))
{
input = input + keyInfo.KeyChar;
Console.Write(keyInfo.KeyChar);
}
if (keyInfo.Key == ConsoleKey.Enter)
{
Console.WriteLine();
break;
}
if (keyInfo.Key == ConsoleKey.Backspace)
{
input = input.Substring(0, input.Length - 1);
Console.Write("\b \b");
}
} while (true);
return input;
}
}
This will allow the user to enter only numbers. You could filter it anyway you want, if you wanted to. For example, only letters and numbers, etc...
As it stands right now, it only allows integer numbers. If you want to allow a decimal point, change the line above to this: if (char.IsNumber(keyInfo.KeyChar) || keyInfo.KeyChar == '.')
You could write a method that reads key by key (not displaying in the console), ignores non-numeric characters, prints valid characters and appends them to a StringBuilder instance, like so:
public static string ReadOnlyNumbers()
{
StringBuilder input = new StringBuilder();
ConsoleKeyInfo ckey;
while ((ckey = Console.ReadKey(true)).Key != ConsoleKey.Enter)
{
if (Char.IsDigit(ckey.KeyChar))
{
Console.Write(ckey.KeyChar);
input.Append(ckey.KeyChar);
}
if (ckey.Key == ConsoleKey.Backspace)
{
input.Length--;
Console.Write("\b \b");
}
}
Console.Write(Environment.NewLine);
return input.ToString();
}
You could then use it like this:
string input = ReadOnlyNumbers();
Console.WriteLine(input);
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;
}
}
}
}
I am doing some C# exercises, the assignment is to check if att Swedish SSN is issued to a woman or a man.
The algorithm checks if the ninth number is equally dividable by 0, then it's a woman or else a man.
If I use a hardcoded "nr" in a string variable, the algorithm works, but if I try to read it from a readline statement, I get the following error:
Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: startIndex
This is the code I am using:
//string personnr = "860215-2097";
string personnr = "";
char[] arr;
public void CheckGender(string pnr)
{
arr = personnr.ToCharArray(9, 1);
if (personnr[9] %2 == 0)
{
Console.WriteLine($"Woman!!!");
}
else
{
Console.WriteLine($"Man!!!");
}
}
public void PrintPersonNr()
{
Console.WriteLine("Write a personnr in the format yymmdd-nnnn: ");
string nr = Console.ReadLine();
CheckGender(nr);
}
So it's my PrintPersonNr method that's not working properly I guess..
You can try this:
public enum SSNGender
{
Female,
Male
}
class Program
{
static public Dictionary<SSNGender, string> SSNGenderText
= new Dictionary<SSNGender, string>()
{
{ SSNGender.Female, "Woman" },
{ SSNGender.Male, "Man" },
};
static public SSNGender CheckSSNGender(string pnr)
{
// Here check the validity of the pnr (length, format...)
return pnr[9] % 2 == 0 ? SSNGender.Female : SSNGender.Male;
}
static void Main(string[] args)
{
Console.WriteLine("Write a personnr in the format yymmdd-nnnn: ");
string nr = Console.ReadLine();
var result = CheckSSNGender(nr);
Console.WriteLine(SSNGenderText[result]);
Console.ReadKey();
}
Try following :
public void CheckGender(string pnr)
{
string arr = pnr.Substring(10, 1);
if (arr == "0")
{
Console.WriteLine("Woman!!!");
}
else
{
Console.WriteLine("Man!!!");
}
}
What you need to do is to use the modulus operator and then to check if this number is then divisible by two and if the result is zero then it is even.
There is a fundamental issue as well, you would need to check if the character is a number or not. if it is then the operation would need to then be completed, if not you need to let the user know.
I have modified JDWeng post
public void CheckGender(string pnr)
{
string arr = pnr.Substring(9, 1);
int num =0;
if (int.TryParse(arr, num))
{
if ((num % 2) == "0")
{
Console.WriteLine("Man!!!");
}
else
{
Console.WriteLine("Woman!!!");
}
}
else
{
Console.WriteLine("Not a number!");
}
}
Best of luck in your exercise as well!!!
I am new to the programing c#. I tried to program a simple program that would run in cmd. I thought that it would randomly creat a noumber and the user would put in the numbers and he/she would try to guess the randomly created one. The program would tell you if it is lower or higher then the number you putted in... I started programing but I came to the problem... I can not compare noumber putted in by user and the randomly generated one.
This is the code...
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Guess the number!");
Random randomObject = new Random();
int RandNoumber = randomObject.Next(9999) + 1;
ConsoleKeyInfo keyinfo = Console.ReadKey();
if (keyinfo < RandNoumber) //This is where I got an error msg
{
}
}
}
Thank you for all the support!
MP
You could use Consol.ReadLine and then parse the value the user entered
static void Main(string[] args)
{
Console.WriteLine("Guess the number!");
Random randomObject = new Random();
int RandNoumber = randomObject.Next(9999) + 1;
int enteredNumber;
while (true)
{
bool parsed = int.TryParse(Console.ReadLine(), out enteredNumber);
if (parsed)
{
if (enteredNumber < RandNoumber)
{
Console.WriteLine("Wrong it's higher");
}
else if (enteredNumber > RandNoumber)
{
Console.WriteLine("Wrong it's lower");
}
else
{
Console.WriteLine("Good Job!");
//Do victory dance
return;
}
}
else
{
Console.WriteLine("Please enter a number");
}
}
}
Console.WriteLine("Enter the cost of the item");
string input = Console.ReadLine();
double price = Convert.ToDouble(input);
Hello, I want the keyboard buttons, A-Z, brackets, question mark, etc to be disabled. I want it so if you type it in, it will not show up in the Console. I only want the numbers 1-9 to show up. This is in C# Console application. Thanks for the help!
try this code snippet
string _val = "";
Console.Write("Enter your value: ");
ConsoleKeyInfo key;
do
{
key = Console.ReadKey(true);
if (key.Key != ConsoleKey.Backspace)
{
double val = 0;
bool _x = double.TryParse(key.KeyChar.ToString(), out val);
if (_x)
{
_val += key.KeyChar;
Console.Write(key.KeyChar);
}
}
else
{
if (key.Key == ConsoleKey.Backspace && _val.Length > 0)
{
_val = _val.Substring(0, (_val.Length - 1));
Console.Write("\b \b");
}
}
}
// Stops Receving Keys Once Enter is Pressed
while (key.Key != ConsoleKey.Enter);
Console.WriteLine();
Console.WriteLine("The Value You entered is : " + _val);
Console.ReadKey();
This MSDN article explains how to read characters one at a time in a console window. Test each character as it is input with the Char.IsNumber() method, and reject those characters that fail the test.
In a while, I got a solution really short:
double number;
Console.Write("Enter the cost of the item: ");
while (!double.TryParse(Console.ReadLine(), out number))
{
Console.Write("This is not valid input. Please enter an integer value: ");
}
Console.Write("The item cost is: {0}", number);
See you!
Here is one approach. It's probably overkill if you're just starting out in C#, since it uses some more advanced aspects of the language. In any case, I hope you find it interesting.
It has some nice features:
The ReadKeys method takes an arbitrary function for testing whether the string so far is valid. This makes it easy to reuse whenever you want filtered input from the keyboard (e.g. letters or numbers but no punctuation).
It should handle anything you throw at it that can be interpreted as a double, e.g. "-123.4E77".
However, unlike John Woo's answer it doesn't handle backspaces.
Here is the code:
using System;
public static class ConsoleExtensions
{
public static void Main()
{
string entry = ConsoleExtensions.ReadKeys(
s => { StringToDouble(s) /* might throw */; return true; });
double result = StringToDouble(entry);
Console.WriteLine();
Console.WriteLine("Result was {0}", result);
}
public static double StringToDouble(string s)
{
try
{
return double.Parse(s);
}
catch (FormatException)
{
// handle trailing E and +/- signs
return double.Parse(s + '0');
}
// anything else will be thrown as an exception
}
public static string ReadKeys(Predicate<string> check)
{
string valid = string.Empty;
while (true)
{
ConsoleKeyInfo key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter)
{
return valid;
}
bool isValid = false;
char keyChar = key.KeyChar;
string candidate = valid + keyChar;
try
{
isValid = check(candidate);
}
catch (Exception)
{
// if this raises any sort of exception then the key wasn't valid
// one of the rare cases when catching Exception is reasonable
// (since we really don't care what type it was)
}
if (isValid)
{
Console.Write(keyChar);
valid = candidate;
}
}
}
}
You also could implement an IsStringOrDouble function that returns false instead of throwing an exception, but I leave that as an exercise.
Another way this could be extended would be for ReadKeys to take two Predicate<string> parameters: one to determine whether the substring represented the start of a valid entry and one the second to say whether it was complete. In that way we could allow keypresses to contribute, but disallow the Enter key until entry was complete. This would be useful for things like password entry where you want to ensure a certain strength, or for "yes"/"no" entry.
This code will allow you to:
Write only one dot (because numbers can have only one decimal separator);
One minus at the begining;
One zero at the begining.
It means that you not be able to write something like: "00000.5" or "0000...-5".
class Program
{
static string backValue = "";
static double value;
static ConsoleKeyInfo inputKey;
static void Main(string[] args)
{
Console.Title = "";
Console.Write("Enter your value: ");
do
{
inputKey = Console.ReadKey(true);
if (char.IsDigit(inputKey.KeyChar))
{
if (inputKey.KeyChar == '0')
{
if (!backValue.StartsWith("0") || backValue.Contains('.'))
Write();
}
else
Write();
}
if (inputKey.KeyChar == '-' && backValue.Length == 0 ||
inputKey.KeyChar == '.' && !backValue.Contains(inputKey.KeyChar) &&
backValue.Length > 0)
Write();
if (inputKey.Key == ConsoleKey.Backspace && backValue.Length > 0)
{
backValue = backValue.Substring(0, backValue.Length - 1);
Console.Write("\b \b");
}
} while (inputKey.Key != ConsoleKey.Enter); //Loop until Enter key not pressed
if (double.TryParse(backValue, out value))
Console.Write("\n{0}^2 = {1}", value, Math.Pow(value, 2));
Console.ReadKey();
}
static void Write()
{
backValue += inputKey.KeyChar;
Console.Write(inputKey.KeyChar);
}
}
You can do it with a single line code as follows:
int n;
Console.WriteLine("Enter a number: ");
while (!int.TryParse(Console.ReadLine(), out n)) Console.WriteLine("Integers only allowed."); // This line will do the trick
Console.WriteLine($"The number is {n}");
You can change int into double in case you wanted to allow double instead of integers and so on.
string input;
double price;
bool result = false;
while ( result == false )
{
Console.Write ("\n Enter the cost of the item : ");
input = Console.ReadLine ();
result = double.TryParse (input, out price);
if ( result == false )
{
Console.Write ("\n Please Enter Numbers Only.");
}
else
{
Console.Write ("\n cost of the item : {0} \n ", price);
break;
}
}
Talking console here.
The idea is that if user presses any key except numbers(the ones above the letter keys, and numpad) during an input prompt in the console, then nothing will be typed. Its's as if console will ignore any non-numeric key presses.
How would one do it the right way?
Try the ReadKey method:
while (processing input)
{
ConsoleKeyInfo input_info = Console.ReadKey (true); // true stops echoing
char input = input_info.KeyChar;
if (char.IsDigit (input))
{
Console.Write (input);
// and any processing you may want to do with the input
}
}
private static void Main(string[] args) {
bool inputComplete = false;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
while (!inputComplete ) {
System.ConsoleKeyInfo key = System.Console.ReadKey(true);
if (key.Key == System.ConsoleKey.Enter ) {
inputComplete = true;
}
else if (char.IsDigit(key.KeyChar)) {
sb.Append(key.KeyChar);
System.Console.Write(key.KeyChar.ToString());
}
}
System.Console.WriteLine();
System.Console.WriteLine(sb.ToString() + " was entered");
}
This little experiment works like that:
static void Main()
{
while (true)
{
var key = Console.ReadKey(true);
int i;
if (int.TryParse(key.KeyChar.ToString(), out i))
{
Console.Write(key.KeyChar);
}
}
}