I'm making a program that reverses a string and doesn't allow for anything else than letters and whitespaces, problem is that if i enter a non-valid input and then try to input a valid input it just keeps printing error. I think the problem has something to do with my while loop and the bool result, but i can't figure it out. Please help and thank you!
static void Reverse()
{
string name;
Console.Write("Enter your name: ");
name = Console.ReadLine();
bool result = name.All(c => char.IsWhiteSpace(c) || char.IsLetter(c));
if (Regex.IsMatch(name, #"^[a-zA-Z- ]+$")) // Validates the input for characters and/or spaces
{
char[] charArr = name.ToCharArray();
Array.Reverse(charArr);
string nameRev = new string(charArr);
Console.WriteLine("String is {0}", nameRev);
}
else
{
while (name == String.Empty || result == false) //Should validate the input for whitespace or letter if it doesn't pass the first validation
{
Console.Write("Error! Enter your name, only letters allowed: ");
name = Console.ReadLine();
}
}
You need to wrap your while loop around the hole sequence instead of just having it inside the else statement.
Example:
static void Reverse()
{
// Continues executing as long as result stays false.
bool result;
do
{
string name;
Console.Write("Enter your name: ");
name = Console.ReadLine();
result = name.All(c => char.IsWhiteSpace(c) || char.IsLetter(c));
if (Regex.IsMatch(name, #"^[a-zA-Z- ]+$"))
{
char[] charArr = name.ToCharArray();
Array.Reverse(charArr);
string nameRev = new string(charArr);
Console.WriteLine("String is {0}", nameRev);
}
else
{
Console.WriteLine("Error! Only letters allowed");
}
}
while (!result);
}
public static void GetCommand(string room, string[] items)
{
Console.WriteLine("what would you like to do?");
string UserInput = Console.ReadLine();
Console.WriteLine("UserInput1: ", UserInput);
UserInput = UserInput.ToLower();
string[] uIn = UserInput.Split();
Console.WriteLine("UserInput2: ",uIn);
if (uIn[0] == "get")
{
get(room, items, uIn);
GetCommand(room,items);
}
if (uIn[0] == "search")
{
search(room, uIn);
}
if (uIn[0]== "north" ^ uIn[0] == "south" ^ uIn[0] == "east" ^ uIn[0] == "west")
{
Console.WriteLine(":::", uIn[0]);
move(room, uIn[0]);
}
if (uIn[0] == "test")
{
test();
}
if (uIn[0] == "clear")
{
Console.Clear();
}
}
I'm not sure why the UserInput is null and why the seeming simple user input isn't working. I am very new to c# so the code isn't good, sorry in advance.
Your UserInput isn't null it's the printing problem...
When you print you can do it in two ways :
Console.WriteLine("UserInput1 : "+UserInput); //use + not ,
Console.WriteLine("UserInput1 : {0}" , UserInput); //inside the {} u type the position of the parameter {0} is first and {1} is second
Note that when you give parameter you use the ,
The problem you had is that you gave parameter while didn't said to print it (didn't use {0})
I created a User login and password program where a user has to type in a username and a password. I have my usernames and passwords in parallel arrays. If a user types the username or password wrong for the first time they get a message saying "Username is incorrect try again" or "password is incorrect try again".
My problem is if the user types in the wrong username for the first time they get the error message, but if the user type in the right username for the second time they still get the error message.
What I found out is when they get it wrong for the first time the program asks them to input the second username instead of the first one. How can I fix this so the program lets the user type in the first username instead of asking for the second username?
// The available usernames and passwords a user can input
string[] username = {"BUL","GVL","UDF","RFT","WDR" };
int[] password = {100, 200, 300, 400, 500 };
Console.WriteLine("\nUsername,Password \nBUL,100 \nGVL,200 \nUDF,300 \nRFT,400 \nWDR,500 ");
// Loop for Username Input
for (int i = 0; i < username.Length; i++)
{
Console.WriteLine("Enter Username");
string inputUsername = Console.ReadLine();
// if user type a wrong username, they need to try again
if (username[i] != inputUsername)
{
Console.WriteLine("Incorrect Username, Try again");
}
else
break;
}
How about using a Dictionary to store the usernames and passwords as Key-Value-Pairs instead of storing theme in two separate arrays? This way, you can check both username and password in one step.
Dictionary<string, string> dic = new Dictionary<string, string>
{
{ "BUL", "100" },
{ "GVL", "200" },
{ "UDF", "300" },
{ "RFT", "400" },
{ "WDR", "500" }
};
while(true)
{
Console.WriteLine("Enter Username");
string inputUsername = Console.ReadLine();
Console.WriteLine("Enter Password");
string pass = Console.ReadLine();
if (!dic.Contains(new KeyValuePair<string, string>(inputUsername, pass)))
Console.WriteLine("Incorrect Username/password, Try again");
else break;
}
Try this:
bool isUserNameValid = false;
string inputUsername = "";
do
{
Console.WriteLine("Enter Username");
inputUsername = Console.ReadLine();
for ( int i = 0; i < username.Length; i++ )
if ( username[i] == inputUsername )
{
isUserNameValid = true;
break;
}
if ( !isUserNameValid )
Console.WriteLine("Incorrect Username, Try again");
}
while ( !isUserNameValid );
bool isPasswordValid = false;
int inputPassword = 0;
do
{
Console.WriteLine("Enter Password");
int.TryParse(Console.ReadLine(), out inputPassword);
for ( int i = 0; i < password.Length; i++ )
if ( password[i] == inputPassword )
{
isPasswordValid = true;
break;
}
if ( !isPasswordValid )
Console.WriteLine("Incorrect Password, Try again");
}
while ( !isPasswordValid );
If you want to persist using Array, then you could do as the following code. But it would be always better to use Dictionaries in this scenario, which provides you a mapping between UserName and Password. If you were to use Arrays, you would need to map them yourself based on Array Index.
You can employ two loops, each validating the username and then combination of username/password until it is valid.
string inputUserName,inputPassword;
// Loop for Username Input
while(true)
{
Console.WriteLine("Enter Username");
inputUserName = Console.ReadLine();
if(username.Contains(inputUserName))
break;
else
Console.WriteLine("Incorrect UserName");
}
while(true)
{
Console.WriteLine("Enter Password");
inputPassword = Console.ReadLine();
var indexOfUserName = Array.IndexOf(username,inputUserName);
if(Int32.TryParse(inputPassword,out var value) && password[indexOfUserName] == value)
break;
else
Console.WriteLine("Incorrect Password");
}
While using Dictionary you could change the code as follows.
// Dictionary declaration
var userDictionary = new Dictionary<string,int>
{
{ "BUL", 100 },
{ "GVL", 200 },
{ "UDF", 300 },
{ "RFT", 400 },
{ "WDR", 500 }
};
string inputUserName,inputPassword;
// Loop for Username Input
while(true)
{
Console.WriteLine("Enter Username");
inputUserName = Console.ReadLine();
if(userDictionary.Keys.Contains(inputUserName))
break;
else
Console.WriteLine("Incorrect UserName");
}
while(true)
{
Console.WriteLine("Enter Password");
inputPassword = Console.ReadLine();
if(Int32.TryParse(inputPassword,out var value) && userDictionary[inputUserName] == value)
break;
else
Console.WriteLine("Incorrect UserName");
}
If you would like to further eliminate some duplicate code, you could refactor the code as following.
var userDictionary = new Dictionary<string,int>
{
{ "BUL", 100 },
{ "GVL", 200 },
{ "UDF", 300 },
{ "RFT", 400 },
{ "WDR", 500 }
};
Console.WriteLine("\nUsername,Password \nBUL,100 \nGVL,200 \nUDF,300 \nRFT,400 \nWDR,500 ");
var userName = ReadFromUserTillTrue("Enter UserName","Incorrect UserName",x=>userDictionary.Keys.Contains(x));
var password = ReadFromUserTillTrue("Enter Password","Incorrect Password",x=>Int32.TryParse(x,out var value) && userDictionary[userName]== value);
Where ReadFromUserTillTrueis defined as
public string ReadFromUserTillTrue(string promptMessage,string errorMessage,Func<string,bool> validator)
{
var input = string.Empty;
while(true)
{
Console.WriteLine(promptMessage);
input = Console.ReadLine();
if(validator(input))
break;
else
Console.WriteLine(errorMessage);
}
return input;
}
Besides realy great answers in this thread, I'd also recommend to check Polly.NET framework. When I need to do something with retries I find it already has something that serves my needs. Below is an example of how you can implement retries with countdown (and there is many more other nice things in the framework):
var usernames = new List<string>(){ "BUL", "GVL", "UDF", "RFT", "WDR" };
int[] passwords = { 100, 200, 300, 400, 500 };
var user = Policy
.HandleResult<String>(r => !usernames.Contains(r))
.RetryForever((r)=> Console.WriteLine($"Username is incorrect, Try again"))
.Execute(() => {
Console.WriteLine("Enter Username:");
return Console.ReadLine();
});
var expectedPassword = passwords[usernames.IndexOf(user)];
var maxRetries = 5;
Policy
.HandleResult<int>(r => r != expectedPassword)
.Retry(maxRetries, (r, i) => Console.WriteLine($"Password is incorrect. Retries left: {maxRetries - i + 1}"))
.Execute(() => {
Console.WriteLine("Enter Password:");
// should here also be a retry? try do that with Polly :)
int.TryParse(Console.ReadLine(), out var password);
return password;
});
I'm following a tutorial and while trying to solve one of the challenges I came across these error messages:
Field 'Data.Age' is never assigned to, and will always have its default value 0
Field 'Data.Month' is never assigned to, and will always have its default value null
The code is runnig fine and everything works but I don't know what this error exactly means (because I assigned something to those fields) or how to fix it.
I looked into How to fix "Field X is never assigned to and will have its default value null"? but didn't understand what's going on.
class Program
{
static void Main(string[] args)
{
var data = new Data();
Console.WriteLine("What is your name?");
data.Name = Console.ReadLine();
while (data.Name == "")
{
data.Name = TryAgain();
}
Console.WriteLine("What is your age?");
data.Age = int.Parse(Console.ReadLine());
while (data.Age == null)
{
data.Age = int.Parse(TryAgain());
}
Console.WriteLine("What month were you born in?");
data.Month = Console.ReadLine();
while (data.Month == "")
{
data.Month = TryAgain();
}
Console.WriteLine("Your name is: {0}", data.Name);
Console.WriteLine("Your age is: {0}", data.Age);
Console.WriteLine("Your birth month is: {0}", data.Month);
}
static string TryAgain()
{
Console.WriteLine("You didn't type anything, please try again:");
return Console.ReadLine();
}
}
class Data
{
public string Name;
public int? Age;
public string Month;
}
So I want to make a list of names. I want this list to go on until user inputs 0 to quit, after user types 0 I want all names to be displayed. You probably see what I'm trying to do from the code below...that "typedName" is there just so you see what I'm trying to do.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string>();
Console.WriteLine("Type in 0 to end.");
bool over = false;
while (over != true)
{
names.Add(Console.ReadLine());
if(typedName == "0")
{
over = true;
}
}
Console.WriteLine("Entered names : ");
names.ForEach(Console.WriteLine);
Console.ReadLine();
}
}
}
First you need the typedName to be captured and then check if it is equal to 0.
if it is not add it to the list
List<string> names = new List<string>();
Console.WriteLine("Type in 0 to end.");
while (true)
{
var typedName = Console.ReadLine();
if (typedName.Equals("0"))
{
break;
}
names.Add(typedName);
}
Console.WriteLine("Entered names : ");
foreach(var name in names)
{
Console.WriteLine(name);
}
Console.ReadLine();
if(typedName == "0")
Well, what is typedName? Or what should it be? I suspect it should be the input entered by the user, something like this:
var typedName = Console.ReadLine();
You can then add it to the list by using that variable:
names.Add(typedName);
And compare it with "0" as you already do, etc.
your code is not complete that is why is not working...
you are missing the most important part:
populate the list if and only if typedName != "0"
while (!over)
{
var typedName =Console.ReadLine();
if(typedName == "0")
{
over = true;
}else
{
Console.WriteLine("Enter a name... ");
names.Add(Console.ReadLine());
}
...
}