I tried the following code...
string pass = "";
Console.Write("Enter your password: ");
ConsoleKeyInfo key;
do
{
key = Console.ReadKey(true);
// Backspace Should Not Work
if (key.Key != ConsoleKey.Backspace)
{
pass += key.KeyChar;
Console.Write("*");
}
else
{
Console.Write("\b");
}
}
// Stops Receving Keys Once Enter is Pressed
while (key.Key != ConsoleKey.Enter);
Console.WriteLine();
Console.WriteLine("The Password You entered is : " + pass);
But this way the backspace functionality doesn't work while typing the password.
Any suggestion?
Console.Write("\b \b"); will delete the asterisk character from the screen, but you do not have any code within your else block that removes the previously entered character from your pass string variable.
Here's the relevant working code that should do what you require:
var pass = string.Empty;
ConsoleKey key;
do
{
var keyInfo = Console.ReadKey(intercept: true);
key = keyInfo.Key;
if (key == ConsoleKey.Backspace && pass.Length > 0)
{
Console.Write("\b \b");
pass = pass[0..^1];
}
else if (!char.IsControl(keyInfo.KeyChar))
{
Console.Write("*");
pass += keyInfo.KeyChar;
}
} while (key != ConsoleKey.Enter);
For this you should use the System.Security.SecureString
public SecureString GetPassword()
{
var pwd = new SecureString();
while (true)
{
ConsoleKeyInfo i = Console.ReadKey(true);
if (i.Key == ConsoleKey.Enter)
{
break;
}
else if (i.Key == ConsoleKey.Backspace)
{
if (pwd.Length > 0)
{
pwd.RemoveAt(pwd.Length - 1);
Console.Write("\b \b");
}
}
else if (i.KeyChar != '\u0000' ) // KeyChar == '\u0000' if the key pressed does not correspond to a printable character, e.g. F1, Pause-Break, etc
{
pwd.AppendChar(i.KeyChar);
Console.Write("*");
}
}
return pwd;
}
Complete solution, vanilla C# .net 3.5+
Cut & Paste
:)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleReadPasswords
{
class Program
{
static void Main(string[] args)
{
Console.Write("Password:");
string password = Orb.App.Console.ReadPassword();
Console.WriteLine("Sorry - I just can't keep a secret!");
Console.WriteLine("Your password was:\n<Password>{0}</Password>", password);
Console.ReadLine();
}
}
}
namespace Orb.App
{
/// <summary>
/// Adds some nice help to the console. Static extension methods don't exist (probably for a good reason) so the next best thing is congruent naming.
/// </summary>
static public class Console
{
/// <summary>
/// Like System.Console.ReadLine(), only with a mask.
/// </summary>
/// <param name="mask">a <c>char</c> representing your choice of console mask</param>
/// <returns>the string the user typed in </returns>
public static string ReadPassword(char mask)
{
const int ENTER = 13, BACKSP = 8, CTRLBACKSP = 127;
int[] FILTERED = { 0, 27, 9, 10 /*, 32 space, if you care */ }; // const
var pass = new Stack<char>();
char chr = (char)0;
while ((chr = System.Console.ReadKey(true).KeyChar) != ENTER)
{
if (chr == BACKSP)
{
if (pass.Count > 0)
{
System.Console.Write("\b \b");
pass.Pop();
}
}
else if (chr == CTRLBACKSP)
{
while (pass.Count > 0)
{
System.Console.Write("\b \b");
pass.Pop();
}
}
else if (FILTERED.Count(x => chr == x) > 0) { }
else
{
pass.Push((char)chr);
System.Console.Write(mask);
}
}
System.Console.WriteLine();
return new string(pass.Reverse().ToArray());
}
/// <summary>
/// Like System.Console.ReadLine(), only with a mask.
/// </summary>
/// <returns>the string the user typed in </returns>
public static string ReadPassword()
{
return Orb.App.Console.ReadPassword('*');
}
}
}
Taking the top answer, as well as the suggestions from its comments, and modifying it to use SecureString instead of String, test for all control keys, and not error or write an extra "*" to the screen when the password length is 0, my solution is:
public static SecureString getPasswordFromConsole(String displayMessage) {
SecureString pass = new SecureString();
Console.Write(displayMessage);
ConsoleKeyInfo key;
do {
key = Console.ReadKey(true);
// Backspace Should Not Work
if (!char.IsControl(key.KeyChar)) {
pass.AppendChar(key.KeyChar);
Console.Write("*");
} else {
if (key.Key == ConsoleKey.Backspace && pass.Length > 0) {
pass.RemoveAt(pass.Length - 1);
Console.Write("\b \b");
}
}
}
// Stops Receving Keys Once Enter is Pressed
while (key.Key != ConsoleKey.Enter);
return pass;
}
Mine ignores control characters and handles line wrapping:
public static string ReadLineMasked(char mask = '*')
{
var sb = new StringBuilder();
ConsoleKeyInfo keyInfo;
while ((keyInfo = Console.ReadKey(true)).Key != ConsoleKey.Enter)
{
if (!char.IsControl(keyInfo.KeyChar))
{
sb.Append(keyInfo.KeyChar);
Console.Write(mask);
}
else if (keyInfo.Key == ConsoleKey.Backspace && sb.Length > 0)
{
sb.Remove(sb.Length - 1, 1);
if (Console.CursorLeft == 0)
{
Console.SetCursorPosition(Console.BufferWidth - 1, Console.CursorTop - 1);
Console.Write(' ');
Console.SetCursorPosition(Console.BufferWidth - 1, Console.CursorTop - 1);
}
else Console.Write("\b \b");
}
}
Console.WriteLine();
return sb.ToString();
}
This masks the password with a red square, then reverts back to the original colours once the password has been entered.
It doesn't stop the user from using copy/paste to get the password, but if it's more just about stopping someone looking over your shoulder, this is a good quick solution.
Console.Write("Password ");
ConsoleColor origBG = Console.BackgroundColor; // Store original values
ConsoleColor origFG = Console.ForegroundColor;
Console.BackgroundColor = ConsoleColor.Red; // Set the block colour (could be anything)
Console.ForegroundColor = ConsoleColor.Red;
string Password = Console.ReadLine(); // read the password
Console.BackgroundColor= origBG; // revert back to original
Console.ForegroundColor= origFG;
Reading console input is hard, you need to handle special keys like Ctrl, Alt, also cursor keys and Backspace/Delete. On some keyboard layouts, like Swedish Ctrl is even needed to enter keys that exist directly on US keyboard. I believe that trying to handle this using the "low-level" Console.ReadKey(true) is just very hard, so the easiest and most robust way is to just to disable "console input echo" during entering password using a bit of WINAPI.
The sample below is based on answer to Read a password from std::cin question.
private enum StdHandle
{
Input = -10,
Output = -11,
Error = -12,
}
private enum ConsoleMode
{
ENABLE_ECHO_INPUT = 4
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetStdHandle(StdHandle nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out int lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetConsoleMode(IntPtr hConsoleHandle, int dwMode);
public static string ReadPassword()
{
IntPtr stdInputHandle = GetStdHandle(StdHandle.Input);
if (stdInputHandle == IntPtr.Zero)
{
throw new InvalidOperationException("No console input");
}
int previousConsoleMode;
if (!GetConsoleMode(stdInputHandle , out previousConsoleMode))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not get console mode.");
}
// disable console input echo
if (!SetConsoleMode(stdInputHandle , previousConsoleMode & ~(int)ConsoleMode.ENABLE_ECHO_INPUT))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not disable console input echo.");
}
// just read the password using standard Console.ReadLine()
string password = Console.ReadLine();
// reset console mode to previous
if (!SetConsoleMode(stdInputHandle , previousConsoleMode))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not reset console mode.");
}
return password;
}
I found a bug in shermy's vanilla C# 3.5 .NET solution which otherwise works a charm. I have also incorporated Damian LeszczyĆski - Vash's SecureString idea here but you can use an ordinary string if you prefer.
THE BUG: If you press backspace during the password prompt and the current length of the password is 0 then an asterisk is incorrectly inserted in the password mask. To fix this bug modify the following method.
public static string ReadPassword(char mask)
{
const int ENTER = 13, BACKSP = 8, CTRLBACKSP = 127;
int[] FILTERED = { 0, 27, 9, 10 /*, 32 space, if you care */ }; // const
SecureString securePass = new SecureString();
char chr = (char)0;
while ((chr = System.Console.ReadKey(true).KeyChar) != ENTER)
{
if (((chr == BACKSP) || (chr == CTRLBACKSP))
&& (securePass.Length > 0))
{
System.Console.Write("\b \b");
securePass.RemoveAt(securePass.Length - 1);
}
// Don't append * when length is 0 and backspace is selected
else if (((chr == BACKSP) || (chr == CTRLBACKSP)) && (securePass.Length == 0))
{
}
// Don't append when a filtered char is detected
else if (FILTERED.Count(x => chr == x) > 0)
{
}
// Append and write * mask
else
{
securePass.AppendChar(chr);
System.Console.Write(mask);
}
}
System.Console.WriteLine();
IntPtr ptr = new IntPtr();
ptr = Marshal.SecureStringToBSTR(securePass);
string plainPass = Marshal.PtrToStringBSTR(ptr);
Marshal.ZeroFreeBSTR(ptr);
return plainPass;
}
(My) nuget package to do this, based on the top answer:
install-package PanoramicData.ConsoleExtensions
Usage:
using PanoramicData.ConsoleExtensions;
...
Console.Write("Password: ");
var password = ConsolePlus.ReadPassword();
Console.WriteLine();
Project URL: https://github.com/panoramicdata/PanoramicData.ConsoleExtensions
Pull requests welcome.
Here's a version that adds support for the Escape key (which returns a null string)
public static string ReadPassword()
{
string password = "";
while (true)
{
ConsoleKeyInfo key = Console.ReadKey(true);
switch (key.Key)
{
case ConsoleKey.Escape:
return null;
case ConsoleKey.Enter:
return password;
case ConsoleKey.Backspace:
if (password.Length > 0)
{
password = password.Substring(0, (password.Length - 1));
Console.Write("\b \b");
}
break;
default:
password += key.KeyChar;
Console.Write("*");
break;
}
}
}
Jeez guys
static string ReadPasswordLine()
{
string pass = "";
ConsoleKeyInfo key;
do
{
key = Console.ReadKey(true);
if (key.Key != ConsoleKey.Enter)
{
if (!(key.KeyChar < ' '))
{
pass += key.KeyChar;
Console.Write("*");
}
else if (key.Key == ConsoleKey.Backspace && pass.Length > 0)
{
Console.Write(Convert.ToChar(ConsoleKey.Backspace));
pass = pass.Remove(pass.Length - 1);
Console.Write(" ");
Console.Write(Convert.ToChar(ConsoleKey.Backspace));
}
}
} while (key.Key != ConsoleKey.Enter);
return pass;
}
You could append your keys to an accumulating linked list.
When a backspace key is received, remove the last key from the list.
When you receive the enter key, collapse your list into a string and do the rest of your work.
I made some changes for backspace
string pass = "";
Console.Write("Enter your password: ");
ConsoleKeyInfo key;
do
{
key = Console.ReadKey(true);
// Backspace Should Not Work
if (key.Key != ConsoleKey.Backspace)
{
pass += key.KeyChar;
Console.Write("*");
}
else
{
pass = pass.Remove(pass.Length - 1);
Console.Write("\b \b");
}
}
// Stops Receving Keys Once Enter is Pressed
while (key.Key != ConsoleKey.Enter);
Console.WriteLine();
Console.WriteLine("The Password You entered is : " + pass);
I have updated Ronnie's version after spending way too much time trying to enter a password only to find out that I had my CAPS LOCK on!
With this version what ever the message is in _CapsLockMessage will "float" at the end of the typing area and will be displayed in red.
This version takes a bit more code and does require a polling loop. On my computer CPU usage about 3% to 4%, but one could always add a small Sleep() value to decrease CPU usage if needed.
private const string _CapsLockMessage = " CAPS LOCK";
/// <summary>
/// Like System.Console.ReadLine(), only with a mask.
/// </summary>
/// <param name="mask">a <c>char</c> representing your choice of console mask</param>
/// <returns>the string the user typed in</returns>
public static string ReadLineMasked(char mask = '*')
{
// Taken from http://stackoverflow.com/a/19770778/486660
var consoleLine = new StringBuilder();
ConsoleKeyInfo keyInfo;
bool isDone;
bool isAlreadyLocked;
bool isCapsLockOn;
int cursorLeft;
int cursorTop;
ConsoleColor originalForegroundColor;
isDone = false;
isAlreadyLocked = Console.CapsLock;
while (isDone == false)
{
isCapsLockOn = Console.CapsLock;
if (isCapsLockOn != isAlreadyLocked)
{
if (isCapsLockOn)
{
cursorLeft = Console.CursorLeft;
cursorTop = Console.CursorTop;
originalForegroundColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("{0}", _CapsLockMessage);
Console.SetCursorPosition(cursorLeft, cursorTop);
Console.ForegroundColor = originalForegroundColor;
}
else
{
cursorLeft = Console.CursorLeft;
cursorTop = Console.CursorTop;
Console.Write("{0}", string.Empty.PadRight(_CapsLockMessage.Length));
Console.SetCursorPosition(cursorLeft, cursorTop);
}
isAlreadyLocked = isCapsLockOn;
}
if (Console.KeyAvailable)
{
keyInfo = Console.ReadKey(intercept: true);
if (keyInfo.Key == ConsoleKey.Enter)
{
isDone = true;
continue;
}
if (!char.IsControl(keyInfo.KeyChar))
{
consoleLine.Append(keyInfo.KeyChar);
Console.Write(mask);
}
else if (keyInfo.Key == ConsoleKey.Backspace && consoleLine.Length > 0)
{
consoleLine.Remove(consoleLine.Length - 1, 1);
if (Console.CursorLeft == 0)
{
Console.SetCursorPosition(Console.BufferWidth - 1, Console.CursorTop - 1);
Console.Write(' ');
Console.SetCursorPosition(Console.BufferWidth - 1, Console.CursorTop - 1);
}
else
{
Console.Write("\b \b");
}
}
if (isCapsLockOn)
{
cursorLeft = Console.CursorLeft;
cursorTop = Console.CursorTop;
originalForegroundColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("{0}", _CapsLockMessage);
Console.CursorLeft = cursorLeft;
Console.CursorTop = cursorTop;
Console.ForegroundColor = originalForegroundColor;
}
}
}
Console.WriteLine();
return consoleLine.ToString();
}
Here is my simple version.
Every time you hit a key, delete all from console and draw as many '*' as the length of password string is.
int chr = 0;
string pass = "";
const int ENTER = 13;
const int BS = 8;
do
{
chr = Console.ReadKey().KeyChar;
Console.Clear(); //imediately clear the char you printed
//if the char is not 'return' or 'backspace' add it to pass string
if (chr != ENTER && chr != BS) pass += (char)chr;
//if you hit backspace remove last char from pass string
if (chr == BS) pass = pass.Remove(pass.Length-1, 1);
for (int i = 0; i < pass.Length; i++)
{
Console.Write('*');
}
}
while (chr != ENTER);
Console.Write("\n");
Console.Write(pass);
Console.Read(); //just to see the pass
If I understand this correctly, you're trying to make backspace delete both the visible * character on screen and the cached character in your pass variable?
If so, then just change your else block to this:
else
{
Console.Write("\b");
pass = pass.Remove(pass.Length -1);
}
I just improve code from ask I simple and just work
string pass = ""; //create empty password string
Console.Write("Enter your password: ");
ConsoleKeyInfo key;
int passLen = 0; // base password length
do
{
key = Console.ReadKey(true); //reading keyboard key
if (key.Key == ConsoleKey.Escape) Environment.Exit(0); // If key is escape console will close (optional)
if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter) // on key with is not bacspase and enter
{
pass += key.KeyChar; //password string add key value
Console.Write("*"); // and print star as masked char
passLen++; // upgrading password length
}
else if (passLen > 0 && key.Key == ConsoleKey.Backspace) //if password have a any symbol and u press Backspace
{
Console.Write("\b \b"); //Backspace delete star symbol and coursor back in line
passLen--; // password length is one less
pass = pass[0..^1]; // new string passowrd is string without last charter
}
}
while (key.Key != ConsoleKey.Enter); // if you press enter this stop execute with your password
Console.WriteLine();
Console.WriteLine("The Password You entered is : " + pass);
string pass = "";
Console.WriteLine("Enter your password: ");
ConsoleKeyInfo key;
do {
key = Console.ReadKey(true);
if (key.Key != ConsoleKey.Backspace) {
pass += key.KeyChar;
Console.Write("*");
} else {
Console.Write("\b \b");
char[] pas = pass.ToCharArray();
string temp = "";
for (int i = 0; i < pass.Length - 1; i++) {
temp += pas[i];
}
pass = temp;
}
}
// Stops Receving Keys Once Enter is Pressed
while (key.Key != ConsoleKey.Enter);
Console.WriteLine();
Console.WriteLine("The Password You entered is : " + pass);
//Gender Creation:
while (correct == 0)
{
do
{
Console.Clear();
Console.WriteLine("Please choose a gender from the options below: ");
Console.WriteLine("Male|Female|Random");
Console.Write("Input: ");
Gender = Console.ReadLine().ToUpper();
if (Gender == "MALE")
{
Console.WriteLine("Is this the gender you wish your character to be? Enter Yes/No: ");
Console.Write("Input: ");
Input = Console.ReadLine().ToUpper();
if (Input == "YES")
{
correct = 1;
}
else if (Input == "NO")
{
correct = 0;
}
}
else if (Gender == "FEMALE")
{
Console.WriteLine("Is this the gender you wish your character to be? Enter Yes/No: ");
Console.Write("Input: ");
Input = Console.ReadLine().ToUpper();
if (Input == "YES")
{
correct = 1;
}
else if (Input == "NO")
{
correct = 0;
}
}
else if (Gender == "RANDOM")
{
correct = 2;
}
else
{
Console.WriteLine("ERROR, Please try again.");
Gender = Console.ReadLine().ToUpper();
}
} while (correct == 0);
//Random Gender Creation:
if (correct == 2)
{
do
{
if (randgender == 1)
{
Console.WriteLine("The gender: MALE was randomly chosen");
Console.WriteLine("Is this the gender you wish your character to be? Enter Yes/No: ");
Console.Write("Input: ");
Input = Console.ReadLine().ToUpper();
if (Input == "YES")
{
correct = 1;
Gender = "MALE";
}
else if (Input == "NO")
{
correct = 2;
}
}
else if (randgender == 2)
{
Console.WriteLine("The gender: FEMALE was randomly chosen");
Console.WriteLine("Is this the race you wish your character to be? Enter Yes/No: ");
Console.Write("Input: ");
Input = Console.ReadLine().ToUpper();
if (Input == "YES")
{
correct = 1;
Gender = "FEMALE";
}
else if (Input == "NO")
{
correct = 2;
}
}
} while (correct == 2);
correct = 0;
}
break;
}
When correct = 2 then the gender is being randomly generated, if the user inputs no when being asked if they are happy with the gender the code will just loop the random gender generator over and over constantly saying that the random gender is the same every time as the random number is never changing however when correct = 0 the code will just proceed when no is inputted and when the gender is printed it is just printed as RANDOM as that is the option the user initially chose.
How can I make it go back to the first do while loop to ask the user what gender they want their character to be?
As theMayer suggested, you'll need to break down your app into smaller pieces. There are also a few concepts that you may need to tackle before you can write C#, as such.
This example might help you get a little further along, as it illustrates several ways of achieving better control flow:
static void Main(string[] args)
{
Console.Clear();
var choosenGender = "";
var wasChoiceConfirmed = false;
while (wasChoiceConfirmed == false)
{
choosenGender = PromptForGender();
switch (choosenGender)
{
case "RANDOM":
var randomGender = GenerateRandomGender();
wasChoiceConfirmed = PromptForGenderConfirmation(randomGender, true);
break;
case "MALE":
case "FEMALE":
wasChoiceConfirmed = PromptForGenderConfirmation(choosenGender);
break;
default:
Console.WriteLine("Error, please try again. \n");
break;
}
}
}
static string PromptForGender()
{
Console.Write(
"\nPlease choose a gender from the options below: \n" +
"Male|Female|Random \n" +
"Input:");
return Console.ReadLine().Trim().ToUpper();
}
static bool PromptForGenderConfirmation(string gender, bool wasRandom = false)
{
var randomVerbiage = wasRandom ? "randomly " : "";
Console.Write(
$"\nThe gender: {gender} was {randomVerbiage}chosen \n" +
"Is this the gender you wish your character to be? Enter Yes/No: \n" +
"Input: ");
var confirmed = Console.ReadLine().Trim().ToUpper();
return confirmed == "YES";
}
static string GenerateRandomGender()
{
var randomNumber = new Random();
return randomNumber.Next(0, 1) == 0 ? "FEMALE" : "MALE";
}
I refactored your code so it helps me understand it better. This gives you the result you want and you don't need all those nested loops.
public class Program
{
public static void AskFirstQuestion()
{
Console.Clear();
Console.WriteLine("Please choose a gender from the options below: ");
Console.WriteLine("Male|Female|Random");
Console.Write("Input: ");
var gender = Console.ReadLine()?.ToUpper();
if (gender == "MALE" || gender == "FEMALE")
{
HandleGenderSelection(gender);
}
else if (gender == "RANDOM")
{
HandleRandom();
}
}
private static void HandleRandom()
{
var randomGender = GenerateRandomGender();
Console.WriteLine($"The gender: {randomGender} was randomly chosen");
Console.WriteLine("Is this the race you wish your character to be? Enter Yes/No: ");
Console.Write("Input: ");
var input = Console.ReadLine()?.ToUpper();
switch (input)
{
case "YES":
Console.WriteLine("OK");
break;
case "NO":
AskFirstQuestion();
break;
}
}
private static string GenerateRandomGender()
{
//Have you logic to randomly create gender
return "MALE";
}
private static void HandleGenderSelection(string gender)
{
Console.WriteLine("Is this the gender you wish your character to be? Enter Yes/No: ");
Console.Write("Input: ");
var input = Console.ReadLine()?.ToUpper();
if (input == "YES")
{
Console.WriteLine("OK!");
}
else if (input == "NO")
{
AskFirstQuestion();
}
}
static void Main(string[] args)
{
AskFirstQuestion();
}
}
I am trying to go back to start in c# console program, and i am somehow able to do it, but the problem is that i am not able to do it using the Y/N statement. mean if i type the Y (yes) from keyboard then the program start from it's starting (beginning) point if i type N then it will terminate the program.
My Console code is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace simple_calculation
{
class Program
{
static void Main(string[] args)
{
bool bktop = true;
string option;
while (bktop)
{
Console.WriteLine("Please enter the values");
int val = int.Parse(Console.ReadLine());
int val1 = int.Parse(Console.ReadLine());
int res = val + val1;
int red = val / val1;
Console.WriteLine("Please enter the operator");
string oper=Console.ReadLine();
if (oper == "+")
{
Console.WriteLine("sum is:" + res);
}
else if (oper == "/")
{
Console.WriteLine("division is:" + red);
}
else
{
Console.WriteLine("do you want to continue? enter Y/N");
option = Console.ReadLine();
if(option=="Y")
{
bktop = false;
}
else
{
bktop = true;
}
}
Console.ReadLine();
}
}
}
}
What I want: i want that when the program reaches to the else condition then there is a text appear in the console "do you want to continue? enter Y/N" if the user enter Y then the program start again and if the user enter N then the program will terminate.
Any help will be appreciated.
class Program
{
static void Main(string[] args)
{
// Change 1
bool bktop = true;
string option;
while (bktop)
{
bktop = true;
Console.WriteLine("Please enter the values");
int val = int.Parse(Console.ReadLine());
int val1 = int.Parse(Console.ReadLine());
int res = val + val1;
int red = val / val1;
Console.WriteLine("Please enter the operator");
string oper = Console.ReadLine();
if (oper == "+")
{
Console.WriteLine("sum is:" + res);
}
else if (oper == "/")
{
Console.WriteLine("division is:" + red);
}
else
{
Console.WriteLine("do you want to continue? enter Y/N");
option = Console.ReadLine();
// Change 2
if (option.ToUpper() != "Y")
{
bktop = false;
}
}
}
}
}
I need to decline the ability to write strings in my console application, at the moment, when text is entered instead of numbers, the console crashes.
I have something along the lines of this right now
class Program
{
static void Main(string[] args)
{
string[] names = new string[2];
string age;
bool agetest = false;
Console.WriteLine("Hello, I am the NameBot2000, What is your first name?");
names[0] = Console.ReadLine();
Console.WriteLine("Well done. What is your surname?");
names[1] = Console.ReadLine();
Console.WriteLine("What year were you born in?");
age = Console.ReadLine();
int.Parse(age);
if (Enumerable.Range(0,2015).Contains(age));
int year = 0;
string wow = "";
if (Enumerable.Range(0,31).Contains(year))
wow = "young";
else if (Enumerable.Range(31,51).Contains(year))
wow = "old";
else if (Enumerable.Range(51,500).Contains(year))
wow = "ancient";
Console.WriteLine("Well done. You said your name was {0} {1}, and you are {2} years old!", names[0], names[1], year);
Console.WriteLine("You are so {0}!", wow);
Console.ReadLine();
}
}
I have tried to incorporate a boolean but I am unsure how to compare the variable to check which format it is in.
Thanks heaps in advance!
Instead of Parse, use TryParse.
int age = 0;
if (Int32.TryParse(Console.Readline, out age)
// Correct format.
else
// error!
What TryParse() will do, is take the user input, Try to Parse it to an int, and if successful, will output an int (and a bool = true), otherwise it will output a bool = false.
use a try catch
string age = console.readline();
bool validage = false;
While(!validage)
{
try
{
int myage = int.parse(age);
validage = true;
}
catch
{
console.write("Please Enter an Integer value for age:");
age = console.readline();
}
}
You can check ConsoleKeyInfo to make sure user can only enter digits for age.
Console.WriteLine("Enter Age : ");
ConsoleKeyInfo key;
string ageStr = "";
do
{
key = Console.ReadKey(true);
if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter)
{
if (char.IsNumber(key.KeyChar))//Check if it is a number
{
ageStr += key.KeyChar;
Console.Write(key.KeyChar);
}
}
else
{
if (key.Key == ConsoleKey.Backspace && ageStr.Length > 0)
{
ageStr = ageStr.Substring(0, (ageStr.Length - 1));
Console.Write("\b \b");
}
}
}
while (key.Key != ConsoleKey.Enter);
Console.WriteLine("Age is {0}", ageStr);
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);
}
}
}