blah blah blah is here! blah blah » Close

up1down
link

Hi,

I am looking for ways in console to control user input according to the following examples:

a. a form where the user is requested to enter a name and I want the user from entering any numeric and to block the input as soon as a length limit is reached, say for example 20 characters long.

b. same as above but only accepting numbers and 7 digit long (example 999-9999 for a phone number)

c. where the input is automatically covered by an asterix "*" i.e in a login form wrt to the password

d. I have remarked that using the upward/downward direction key in input sometimes function like DOS doskey. Previous inputs are shown. Are there way to disable this ability?

Thank you in advanced.

T. Nicolas MARIE.

last answered one year ago

1 answers

up1down
link

Here's a program I wrote in response to a similar question on C# Friends which shows how you can control and delimit the input of various types of field (names, integers, decimals, dates, characters and passwords) within a console 'form'.

Rather than use the cursor to move between fields, the program allows the user to enter the whole form and then edit any fields on it before proceeding to the next form or quitting entry.

Although this may not be quite what you want, it should give you a basic framework for building your own console forms and controlling entry:

using System;
using System.Text;
using System.Collections.Generic;

class UserRecord
{
public string Name;
public string Password;
public string Id;
public DateTime Dob;
public char Sex;
public decimal Donations;
}

class UserRecordEntry
{
static ConsoleColor oldBack;
static ConsoleColor oldFore;

static void Main()
{
Console.TreatControlCAsInput = false;
Console.CancelKeyPress += new ConsoleCancelEventHandler(BreakHandler);
List<UserRecord> users = new List<UserRecord>();
int userNum = 1;
bool quit = false;
do // get record
{
Console.Clear();
DrawBox(20,10,60,32,ConsoleColor.Green, ConsoleColor.Black, false);
for (int i = 1 ; i <=6 ; i++)
{
WriteColorString(i.ToString() +".", 23, 11 + 3* i, ConsoleColor.Black, ConsoleColor.White);
}
WriteColorString(" User Record #" + userNum +" ", 32, 10, ConsoleColor.Yellow, ConsoleColor.Blue);
WriteColorString("User Name : ", 26, 14, ConsoleColor.Black, ConsoleColor.Cyan);
WriteColorString("Password : ", 26, 17, ConsoleColor.Black, ConsoleColor.Cyan);
WriteColorString("User Id : ", 26, 20, ConsoleColor.Black, ConsoleColor.Cyan);
WriteColorString("Date Born : ", 26, 23, ConsoleColor.Black, ConsoleColor.Cyan);
WriteColorString("Sex M/F : ", 26, 26, ConsoleColor.Black, ConsoleColor.Cyan);
WriteColorString("Donations : ", 26, 29, ConsoleColor.Black, ConsoleColor.Cyan);
int fieldNum = 1;
bool editMode = false;
UserRecord user = new UserRecord();
do // get fields for record
{
switch (fieldNum)
{
case 1:
// get name
Console.SetCursorPosition(38,14);
user.Name = GetName2(4,18);
break;
case 2:
// get password
Console.SetCursorPosition(38,17);
user.Password = GetPassword(4,10);
break;
case 3:
// get ID
do
{
Console.SetCursorPosition(38,20);
user.Id = GetFourDigitInteger();
}
while (!ValidateRange(long.Parse(user.Id), 0L, 9999L,3));
break;
case 4:
// get dob
do
{
Console.SetCursorPosition(38,23);
user.Dob = GetDate();
}
while(!ValidateRange(user.Dob, DateTime.Now.AddYears(-100), DateTime.Now.AddYears(-18), 4));
break;
case 5:
// get sex
Console.SetCursorPosition(38,26);
user.Sex = GetChar("MF");
break;
case 6:
// get donations
Console.SetCursorPosition(38,29);
user.Donations = GetDecimal(10,2,false);
break;
default:
break; // to prevent compiler from complaining
}
if (!editMode && fieldNum < 6)
fieldNum++;
else
{
if (Console.CursorVisible) Console.CursorVisible = false;
fieldNum = GetOption(6);
if (!Console.CursorVisible) Console.CursorVisible = true;
if (fieldNum < 1)
{
if (fieldNum == -1)
quit = true;
else
userNum++;
users.Add(user);
break;
}
editMode = true;
}
}
while(fieldNum > 0);
// processing for individual record
}
while(!quit);
// processing for all records
Console.Clear();
}

public static void DrawBox (int ucol, int urow, int lcol, int lrow, ConsoleColor back, ConsoleColor fore, bool fill)
{
const char Horizontal = '\u2500';
const char Vertical = '\u2502';
const char UpperLeftCorner = '\u250c';
const char UpperRightCorner = '\u2510';
const char LowerLeftCorner = '\u2514';
const char LowerRightCorner = '\u2518';
string fillLine = fill ? new string(' ',lcol - ucol - 1) : "";
SetColors(back, fore);
// draw top edge
Console.SetCursorPosition(ucol, urow);
Console.Write(UpperLeftCorner);
for (int i = ucol + 1; i < lcol; i++)
{
Console.Write(Horizontal);
}
Console.Write(UpperRightCorner);

// draw sides
for (int i = urow + 1; i < lrow; i++)
{
Console.SetCursorPosition(ucol, i);
Console.Write(Vertical);
if (fill) Console.Write(fillLine);
Console.SetCursorPosition(lcol, i);
Console.Write(Vertical);
}
// draw bottom edge
Console.SetCursorPosition(ucol, lrow);
Console.Write(LowerLeftCorner);
for (int i = ucol + 1; i < lcol; i++)
{
Console.Write(Horizontal);
}
Console.Write(LowerRightCorner);
RestoreColors();
}

// overload to use current background and foreground colors
public static void DrawBox (int ucol, int urow, int lcol, int lrow, bool fill)
{
DrawBox (ucol, urow, lcol, lrow, Console.BackgroundColor, Console.ForegroundColor, fill);
}

public static void WriteColorString(string s, int col, int row, ConsoleColor back, ConsoleColor fore)
{
SetColors(back, fore);
// write string
Console.SetCursorPosition(col, row);
Console.Write(s);
RestoreColors();
}

public static void SetColors(ConsoleColor back, ConsoleColor fore)
{
// save current background and foreground colors
oldBack = Console.BackgroundColor;
oldFore = Console.ForegroundColor;
// set them to new colors
Console.BackgroundColor = back;
Console.ForegroundColor = fore;
}

public static void RestoreColors()
{
// restore original colors
Console.BackgroundColor = oldBack;
Console.ForegroundColor = oldFore;
}

public static string GetName(int minLength, int maxLength)
{
SetColors(ConsoleColor.White, ConsoleColor.Black);
string blank = new string(' ', maxLength + 2);
int startCol = Console.CursorLeft;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
StringBuilder sb = new StringBuilder();
char key;
// only permit letters, spaces, hyphens and apostrophes
//continue until return pressed provided minimum length reached
do
{
while ((key = Console.ReadKey(true).KeyChar) != '\r')
{
if (key == '\b' && sb.Length > 0) // backspace
{
Console.Write(key + " " + key);
sb = sb.Remove(sb.Length - 1, 1);
}
else if (sb.Length == maxLength)
{
Console.Beep();
}
else if (Char.IsLetter(key))
{
Console.Write(key);
sb = sb.Append(key);
}
else if ((key == ' ' || key == '-' || key == '\'') && sb.Length > 0)
{
Console.Write(key);
sb = sb.Append(key);
}
}
}
while(sb.Length < minLength);
RestoreColors();
SetColors(ConsoleColor.Black, ConsoleColor.White);
Console.CursorLeft = startCol;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
string name = sb.ToString();
Console.WriteLine(name);
return name;
}


public static string GetPassword(int minLength, int maxLength)
{
SetColors(ConsoleColor.White, ConsoleColor.Black);
string blank = new string(' ', maxLength + 2);
int startCol = Console.CursorLeft;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
StringBuilder sb = new StringBuilder();
char key;
// only permit letters or digits
//continue until return pressed provided minimum length reached
do
{
while ((key = Console.ReadKey(true).KeyChar) != '\r')
{
if (key == '\b' && sb.Length > 0) // backspace
{
Console.Write(key + " " + key);
sb = sb.Remove(sb.Length - 1, 1);
}
else if (sb.Length == maxLength)
{
Console.Beep();
}
else if (Char.IsLetterOrDigit(key))
{
Console.Write("x");
sb = sb.Append(key);
}
}
}
while (sb.Length < minLength);
RestoreColors();
SetColors(ConsoleColor.Black, ConsoleColor.White);
Console.CursorLeft = startCol;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
Console.WriteLine(new string('x', sb.Length));
return sb.ToString();
}

public static long GetInteger(int maxLength, bool signed)
{
SetColors(ConsoleColor.White, ConsoleColor.Black);
string blank = new string(' ', maxLength + 2);
int startCol = Console.CursorLeft;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
StringBuilder sb = new StringBuilder();
char key;
// only permit digits or (if signed) initial minus sign
//continue until return pressed
while ((key = Console.ReadKey(true).KeyChar) != '\r')
{
if (key == '\b' && sb.Length > 0) // backspace
{
Console.Write(key + " " + key);
sb = sb.Remove(sb.Length - 1, 1);
}
else if (sb.Length == maxLength)
{
Console.Beep();
}
else if (key == '-' && sb.Length == 0 && signed)
{
Console.Write(key);
sb = sb.Append(key);
}
else if (Char.IsDigit(key) && !(sb.Length == 1 && sb[0]== '0') && !(sb.Length == 1 && sb[0] == '-' && key == '0'))
{
Console.Write(key);
sb = sb.Append(key);
}
}
RestoreColors();
SetColors(ConsoleColor.Black, ConsoleColor.White);
Console.CursorLeft = startCol;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
string temp = sb.ToString();
if (temp == "-" || temp == "") temp = "0";
Console.WriteLine(temp);
long integer = long.Parse(temp);
return integer;
}

public static decimal GetDecimal(int maxLength, int maxPlaces, bool signed)
{
SetColors(ConsoleColor.White, ConsoleColor.Black);
string blank = new string(' ', maxLength + 2);
int startCol = Console.CursorLeft;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
StringBuilder sb = new StringBuilder();
char key;
int dotPos = 0;
// only permit digits, dot or (if signed) initial minus sign
//continue until return pressed
while ((key = Console.ReadKey(true).KeyChar) != '\r')
{
if (key == '\b' && sb.Length > 0) // backspace
{
Console.Write(key + " " + key);
if (sb.Length == dotPos) dotPos = 0;
sb = sb.Remove(sb.Length - 1, 1);
}
else if (sb.Length == maxLength || (dotPos > 0 && sb.Length == dotPos + maxPlaces))
{
Console.Beep();
}
else if (key == '-' && sb.Length == 0 && signed)
{
Console.Write(key);
sb = sb.Append(key);
}
else if (key == '.' && dotPos == 0)
{
if (sb.Length == 0 || (sb.Length == 1 && sb[0] == '-'))
{
Console.Write('0');
sb = sb.Append('0');
}
Console.Write(key);
sb = sb.Append(key);
dotPos = sb.Length;
}
else if (Char.IsDigit(key) && !(sb.Length == 1 && sb[0]== '0') && !(sb.Length == 1 && sb[0] == '-' && key == '0'))
{
Console.Write(key);
sb = sb.Append(key);
}
}
RestoreColors();
SetColors(ConsoleColor.Black, ConsoleColor.White);
Console.CursorLeft = startCol;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
string temp = sb.ToString();
if (dotPos > 0) temp = temp.TrimEnd('0').TrimEnd('.');
if (temp == "-" || temp == "") temp = "0";
Console.WriteLine(temp);
decimal dec = decimal.Parse(temp);
return dec;
}

public static DateTime GetDate()
{
SetColors(ConsoleColor.White, ConsoleColor.Black);
string blank = " / / ";
int startCol = Console.CursorLeft;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
StringBuilder sb = new StringBuilder();
char key;
// only permit dates of form MM/dd/yyyy
//continue until return pressed
while ((key = Console.ReadKey(true).KeyChar) != '\r')
{
if (key == '\b' && sb.Length > 0) // backspace
{
if (sb.Length == 3 || sb.Length == 6)
{
Console.Write(key + "/" + key);
sb = sb.Remove(sb.Length - 1, 1);
}
Console.Write(key + " " + key);
sb = sb.Remove(sb.Length - 1, 1);
}
else if (sb.Length == 10)
{
Console.Beep();
}
else if (Char.IsDigit(key))
{
bool isValid = true;
switch(sb.Length)
{
case 0:
if (key > '1') isValid = false;
break;
case 1:
if ((sb[0] == '1' && key > '2') || (sb[0] == '0' && key == '0')) isValid = false;
break;
case 3:
int month = int.Parse(sb.ToString().Substring(0,2));
if ((key > '2' && month == 2) || (key > '3' && month != 2)) isValid = false;
break;
case 4:
if ((sb[3] == '3' && key > '1') || (sb[3] == '0' && key == '0')) isValid = false;
break;
case 9:
string prospective = sb.ToString() + key.ToString();
month = int.Parse(prospective.Substring(0,2));
int day = int.Parse(prospective.Substring(3,2));
int year = int.Parse(prospective.Substring(6));
if (month == 2 && day == 29 && !DateTime.IsLeapYear(year)) isValid = false;
break;
default:
break;
}
if (isValid)
{
Console.Write(key);
sb = sb.Append(key);
if (sb.Length == 2 || sb.Length == 5)
{
Console.Write('/');
sb = sb.Append('/');
}
}
else
isValid = true;
}
}
RestoreColors();
SetColors(ConsoleColor.Black, ConsoleColor.White);
Console.CursorLeft = startCol;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
string dateString;
if (sb.Length == 10)
dateString = sb.ToString();
else
dateString = "01/01/0001";
Console.WriteLine(dateString);
DateTime date = DateTime.ParseExact(dateString, "MM/dd/yyyy", null);
return date;
}

public static char GetChar(string choices)
{
SetColors(ConsoleColor.White, ConsoleColor.Black);
string blank = " ";
int startCol = Console.CursorLeft;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
StringBuilder sb = new StringBuilder();
choices = choices.ToUpper();
char key;
// only permit letters or digits within 'choices'
//continue until return pressed
while ((key = Console.ReadKey(true).KeyChar) != '\r')
{
if (key == '\b' && sb.Length > 0) // backspace
{
Console.Write(key + " " + key);
sb = sb.Remove(sb.Length - 1, 1);
}
else if (sb.Length == 1)
{
Console.Beep();
}
else if (Char.IsLetterOrDigit(key))
{
key = Char.ToUpper(key);
if (choices.IndexOf(key) > -1)
{
Console.Write(key);
sb = sb.Append(key);
}
}
}
RestoreColors();
SetColors(ConsoleColor.Black, ConsoleColor.White);
Console.CursorLeft = startCol;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
string character = sb.ToString();
if (character == "") character = choices[0].ToString();
Console.WriteLine(character);
return character[0];
}

public static bool ValidateRange<T>(T field, T minimum, T maximum, int num)
where T:IComparable<T>
{
if ((field.CompareTo(minimum) >= 0) && (field.CompareTo(maximum)) <= 0)
return true;
DrawBox(20,35,60,44,ConsoleColor.Green, ConsoleColor.Black, false);
WriteColorString(" Error Field #" + num + " ", 32, 35, ConsoleColor.Red, ConsoleColor.White);
Console.Beep();
string message;
if (field is DateTime)
{
string f = "MM/dd/yyyy";
string min = ((DateTime)(object)minimum).ToString(f);
string max = ((DateTime)(object)maximum).ToString(f);
message = String.Format("{0} to {1}", min, max);
WriteColorString("Acceptable date range", 23, 37, ConsoleColor.Black, ConsoleColor.White);
WriteColorString(message, 23, 39, ConsoleColor.Black, ConsoleColor.White);
}
else
{
message = String.Format("Must be between {0} and {1}", minimum, maximum);
WriteColorString(message, 23, 38, ConsoleColor.Black, ConsoleColor.White);
}
message = "Press any key to re-enter";
WriteColorString(message, 23, 41, ConsoleColor.Black, ConsoleColor.White);
if (Console.CursorVisible) Console.CursorVisible = false;
Console.ReadKey();
if (!Console.CursorVisible) Console.CursorVisible = true;
DrawBox(20,35,60,44,ConsoleColor.Black, ConsoleColor.Black, true);
return false;
}

public static int GetOption(int maximum)
{
DrawBox(20,35,60,45,ConsoleColor.Green, ConsoleColor.Black, false);
WriteColorString(" Options ", 35, 35, ConsoleColor.Blue, ConsoleColor.White);
string message = String.Format("Press '1' to '{0}' to re-enter field", maximum);
WriteColorString(message, 23, 38, ConsoleColor.Black, ConsoleColor.White);
message = "Press 'N' to enter next record";
WriteColorString(message, 23, 40, ConsoleColor.Black, ConsoleColor.White);
message = "Press 'Q' to quit entry";
WriteColorString(message, 23, 42, ConsoleColor.Black, ConsoleColor.White);
char key;
while (Char.ToUpper(key = Console.ReadKey(true).KeyChar) !='Q')
{
if (Char.ToUpper(key) == 'N') // next record
{
return 0;
}
else if (key >= '1' && key <= (char)(maximum + 48))
{
DrawBox(20,35,60,45,ConsoleColor.Black, ConsoleColor.Black, true);
return (int)key - 48;
}
}
return -1;
}


public static string GetName2(int minLength, int maxLength)
{
SetColors(ConsoleColor.White, ConsoleColor.Black);
string blank = new string(' ', maxLength + 2);
int startCol = Console.CursorLeft;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
StringBuilder sb = new StringBuilder();
ConsoleKeyInfo cki;
char key;
bool insertMode = true;
Console.CursorSize = 25; // size of cursor in insert mode
int pos = 0; // zero-based position of cursor in field
// only permit letters, spaces, hyphens and apostrophes
//continue until return pressed provided minimum length reached
while(true)
{
cki = Console.ReadKey(true);
key = cki.KeyChar;
if (key == '\r') // enter
{
if(sb.Length >= minLength) break;
}
else if (key == '\b' && pos > 0) // backspace
{
if(!(pos == 1 && sb.Length > 1 && (sb[1] == ' ' || sb[1] == '-' || sb[1] == '\'')))
{
Console.Write(key + " " + key);
if (pos < sb.Length)
{
Console.Write(sb.ToString().Substring(pos));
Console.Write(" ");
Console.CursorLeft = startCol + pos;
}
sb = sb.Remove(pos - 1, 1);
pos--;
}
}
else if (cki.Key == ConsoleKey.Delete && sb.Length > 0 && pos < sb.Length)
{
if(!(pos == 0 && sb.Length > 1 && (sb[1] == ' ' || sb[1] == '-' || sb[1] == '\'')))
{
Console.Write(sb.ToString().Substring(pos + 1));
Console.Write(" ");
Console.CursorLeft = startCol + pos + 1;
sb = sb.Remove(pos, 1);
}
}
else if (cki.Key == ConsoleKey.Insert)
{
insertMode = !insertMode;
Console.CursorSize = insertMode ? 25 : 50;
}
else if (cki.Key == ConsoleKey.Home && pos > 0)
{
Console.CursorLeft = startCol + 1;
pos = 0;
}
else if (cki.Key == ConsoleKey.End && pos < sb.Length)
{
Console.CursorLeft = startCol + sb.Length + 1;
pos = sb.Length;
}
else if (cki.Key == ConsoleKey.LeftArrow && pos > 0)
{
Console.CursorLeft--;
pos--;
}
else if (cki.Key == ConsoleKey.RightArrow && pos < sb.Length)
{
Console.CursorLeft++;
pos++;
}
else if (pos == maxLength)
{
Console.Beep();
}
else if (Char.IsLetter(key) || ((key == ' ' || key == '-' || key == '\'') && pos > 0))
{
if (!insertMode)
{
Console.Write(key);
if (pos < sb.Length)
sb[pos] = key;
else
sb = sb.Append(key);
pos++;
}
else if (sb.Length < maxLength)
{
Console.Write(key);
if (pos < sb.Length)
{
Console.Write(sb.ToString().Substring(pos));
Console.CursorLeft = startCol + pos + 2;
sb = sb.Insert(pos,key);
}
else
sb = sb.Append(key);
pos++;
}
else
{
Console.Beep();
}
}
}
RestoreColors();
if (!insertMode) Console.CursorSize = 25;
SetColors(ConsoleColor.Black, ConsoleColor.White);
Console.CursorLeft = startCol;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
string name = sb.ToString();
Console.WriteLine(name);
return name;
}

public static string GetFourDigitInteger()
{
SetColors(ConsoleColor.White, ConsoleColor.Black);
string blank = new string(' ', 6);
int startCol = Console.CursorLeft;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
StringBuilder sb = new StringBuilder();
char key;
// only permit exactly 4 digits
do
{
while ((key = Console.ReadKey(true).KeyChar) != '\r') // return
{
if (key == '\b' && sb.Length > 0) // backspace
{
Console.Write(key + " " + key);
sb = sb.Remove(sb.Length - 1, 1);
}
else if (sb.Length == 4)
{
Console.Beep();
}
else if (Char.IsDigit(key))
{
Console.Write(key);
sb = sb.Append(key);
}
}
}
while(sb.Length < 4);
RestoreColors();
SetColors(ConsoleColor.Black, ConsoleColor.White);
Console.CursorLeft = startCol;
Console.Write(blank);
Console.CursorLeft = startCol + 1;
string integer = sb.ToString();
Console.WriteLine(integer);
return integer;
}


private static void BreakHandler(object sender, ConsoleCancelEventArgs args)
{
// exit gracefully if Control-C or Control-Break pressed
Console.ResetColor();
Console.CursorSize = 25;
Console.Clear();
}
}

Thank you very much. I believe I will need you help as I will try to implement your program codes into mine. This will greatly help me progressing through learning C# while programming. Thousands of Thanks. Nic.

Feedback