Asking the user the same question more than once in C# - c#

Starting my Intro To Programming class and we'll be using C# throughout it. I'm currently writing a practice program to get familiar with C# that asks the user for their name and age and then reads it out to them and asks if it is correct. I want to make it so that if the user wants to change their inputted data for any reason then they can press the "n" key for "no that's not right" and re enter their data. However, I want to re-ask them the questions for their age and name(separately) without having to re-type the code block with the Console.WriteLines and if...else block. I did some research and found that:
the "go-to" statement was made by the devil himself and it's essentially the programming equivalent of a hate crime if I use it
making a new method (and subsequently calling that method in my code) with the block of code asking the question seems to be the way to go about it.
My problem is that while I've (hopefully) figured out that's what I need to do, I can't seem to figure out how exactly to either implement that method nor call it correctly later on.
here is the method I'm trying to create that I want to hold an "if...else" statement asking if the info is correct, incorrect, or re-ask the question if the enter something other than "y" or "n":
public void Question()
{
Console.Write("Could I get your name? (Press enter when you are done) ");
string user_name = Console.ReadLine();
Console.Clear();
Console.Write("Awesome! Now if you could just enter your age: ");
string user_age = Console.ReadLine();
Console.Clear();
Console.WriteLine("So according to the information I have on file here... you are " + user_name + " and you're " + user_age + " years old....");
}
This isn't homework so I don't mind specific pieces of code so I can see how it works and tinker with it to learn :)

Good work on doing some research on your own, and a fairly decent question. And you're on the right track.
So let's first focus on asking the question part. If you look at your Question() method, you can see that you're sort of doing the same thing repeatedly inside it. Yes you're asking different questions, but essentially you're doing three things:
Ask a question.
Get the answer.
Clear the Console.
So, maybe you can put those three things into one method, and the only thing that's variable here is the question, so you can pass the question as a parameter.
static string AskQuestion(string question)
{
Console.Write(question);
var ans = Console.ReadLine();
Console.Clear();
return ans;
}
Alright, a bit better.
Now, how do we repeatedly ask the user a question until we get a satisfactory answer? Loops are a good solution, and particularly either while or do-while which doesn't iterate a set number of times but rather until a condition is fulfilled. I personally like to use do-while in a situation like this.
So what do we have to do there now? Let's break it down. We will write a function, and inside a loop we want to:
- Ask a question and get the answer. Good thing we have a method that does just that.
- Show the user the answer he/she entered.
- Ask the user to confirm if it's good.
- If yes, terminate the loop, and return the answer.
- If not, ask the question again.
Something that looks like this:
static string GetSatisfactoryAnswer(string question)
{
var ans = string.Empty;
bool goodAns = false;
do
{
ans = AskQuestion(question);
Console.WriteLine("You entered {0}. Is that correct?", ans);
var confirm = Console.ReadLine();
if (confirm.ToLower() == "y")
goodAns = true;
} while (!goodAns);
return ans;
}
Now you can call them like this:
static void Main(string[] args)
{
var name = GetSatisfactoryAnswer("Could I get your name? (Press enter when you are done) ");
var age = GetSatisfactoryAnswer("Awesome! Now if you could just enter your age: ");
Console.WriteLine();
Console.WriteLine("Name : {0}", name);
Console.WriteLine("Age : {0}", age);
Console.ReadLine();
}
NOTES
This is only to give you a rough idea, you'll need to do a lot of error handling. Such as, what if the user enters anything other than Y/N for the confirmation?
It's always a good idea to actually get the age as an integer. So use int.TryParse() to convert the string input into an int and then do something about it if a non-numerical value was entered.
In your example, you get both Name and Age at once, then asks use to confirm them later. In my opinion, it's best to finish one thing and start another. In other words, make sure your got a satisfactory answer to Name, then move onto Age, etc. My answer is designed that way.
Hope this helps. Good luck!

Related

Program wait till user Input information [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
First of all, im sorry if this question was already responded by someone, but im new to Stackoverflow and im trying to make my first program in C# with visual studio.
Im making a bank program with object oriented programmation, i already done a few methods so the user can deposit and withdraw money, but i dont know how to apply this methods to the Console. Here is my code, and what im trying to do is pause the program till the user sets the information needed, the money and the string of the note (like 80$ "dinner with Joe").
case "/deposit":
//Make the deposit
account.MakeDeposit(Console.Read(), DateTime.Now,Console.ReadLine());
break;
The requierements of the method are a decimal for the amount, the date time that is not a problem, and the string.
It only takes the first character of the command line, for example if i want to deposit 8000$ it will only take the 8. Then the option for the string doesnt even pop up. I wanted to make like a console feedback too, so when i run the command /deposit it prints like: "How much money?" and that stuff.
I need help to break down the method in parts so i can inject the decimal ammount and the string.
Any advices, tips and tutorials are welcome.
Ty guys!
Break down the parts of your application reading input from the console from the parts of the app that process the data. You can then concentrate on one thing at a time. As such, the call to Console.Read does not belong as an argument to account.MakeDeposit. It makes it hard to debug and you will get a mess at the end.
To wait for user input use string input = Console.ReadLine();
Then to convert the string into an amount use
if( decimal.TryParse(input, out decimal amount))
{
// success! do something with 'amount'
}
else
{
Console.WriteLine("Invalid Input. Expected decimal value");
}
Okay so what i made, as Tarik told me is break down the code, with a method will be better but i created empty variables to store the information code gaved by the user, its a bad way to resolve it but im really new to this so it works for me, here is the code:
case "/deposit":
//Deposit Money
decimal C;
string D;
Console.WriteLine("How much you want to deposit?");
C = Convert.ToDecimal(Console.ReadLine());
Console.WriteLine("Add a note:");
D = Console.ReadLine();
account.MakeDeposit(C, DateTime.Now, D);
Console.WriteLine($"Maked a deposit of {C.ToString()}$!");
break;
Ty guys for the help!
Any way to improve it will be appreciated guys.

Is there a function that can make a OR function in String in IF command

I want to ask how do you make the computer read 2 string commands as in "sunday" or "tuesday" written below
if (a == "sunday/tuesday")
Console.WriteLine("take road 1");
else if (a== "monday/afternon")
Console.WriteLine("take road 2");
else
Console.WriteLine("take road 3");
Thank you
Looks like JSteward answered your original question in the comments, though I'm not sure what you mean by checking "of any afternoon" in your other comments.
If you mean the user could enter "thursday afternoon", and you want to check for the word "afternoon" in a string, you can use day.Contains("afternoon") which will return true if afternoon appears in the string. Keep in mind it's case sensitive, so something like day.ToLower().Contains("afternoon") may be more prudent if the user can enter text themselves.

Trying to fix reading from file C#

I have made a small console application, works fine other than when I enter a pin, will include some code soon, I can enter part of it and it will still log me in, I do not want it to do this, I need the pin to be exact to log in.
Full code can be accessed here: https://pastebin.com/ARX1MqLc
Console.WriteLine("Please insert your credit card by pressing 'Enter'.");
Console.ReadKey();
Console.Write("Please enter your 4-digit PIN: ");
pin = Console.ReadLine();
bool pinVerif = File.ReadAllText("C:/Users/ryanj/OneDrive/Documents/Random code/myApp/pin.txt").Contains(pin);
if(pinVerif == true)
{
verified();
}
else
{
Console.WriteLine("Sorry your PIN was incorrect, please try again or exit the program.");
menu();
}
I did create a file that is called pin.txt, so you will need to create that and put anything in it, but I honestly don't know whats wrong with it.
You need an exact match in this case:
string pinContent = File.ReadAllText("C:/Users/ryanj/OneDrive/Documents/Random code/myApp/pin.txt");
bool pinVerif = (pin == pinContent);
That's because of the way contains works. It compares the string you entered with the whole string and checks to see if that part is in there.
Their are tons of ways to solve this. The easiest is to check if the length of your pin is 4.
if(pinVerif && pin.length==4)
or you could do something more complicated and use i.e. json to store the pins in seperate object.

C# text based game - Returning after wrong option

I'm writing a C# text based game to learn how to code.
I don't know how to explain this, but I wan't my game to be able to recognize if you input a wrong parameter and asks you the question given to you again.
E.g
Code Question: Do you wan't to open that door?
Your Answer: asdhasd
Code Answer: I can't understand that.
Code Question: Do you wan't to open that door?
Normally for this kind of task I write a helper method that takes in a string "prompt" (which is the question being asked to the user) and one or more valid responses. Then the method repeatedly asks the question in a do/while loop whose condition is that the response is one of the valid answers.
Note that it's usually a good idea to give the user some choices for valid input (y/n) so they have some idea why you keep asking them the same question over and over again if they enter something else. Though they may be pleasantly surprised if you accept other answers, like "sure" or "nope".
In the example below, this method returns a bool, and takes in two lists of valid answers: valid true answers, and valid false answers. This way it only returns true or false, but accepts a wide variety of input from the user:
public static bool GetBoolFromUser(string prompt, List<string> validTrueResponses,
List<string> validFalseResponses, StringComparison comparisonType)
{
string response;
// Combine all valid responses for the sake of the loop
var allValidResponses =
validTrueResponses?.Union(validFalseResponses) ?? validFalseResponses;
do
{
Console.Write(prompt);
response = Console.ReadLine();
} while (allValidResponses != null &&
!allValidResponses.Any(r => r.Equals(response, comparisonType)));
// Now return true or false depending on which list the response was found in
return validTrueResponses?.Any(r => r.Equals(response, comparisonType)) ?? false;
}
Then, in our main code we can create two lists of valid responses, pass them along with a prompt to the method above, and we know it will return us a true or false result that we can use to make a decision:
private static void Main()
{
// Add any responses you want to allow to these lists
var trueResponses = new List<string>
{
"y", "yes", "ok", "sure", "indeed", "yep", "please", "true"
};
var falseResponses = new List<string>
{
"n", "no", "nope", "nah", "never", "not on your life", "false"
};
bool openDoor = GetBoolFromUser("Do you want to open the door? (y/n): ",
trueResponses, falseResponses, StringComparison.OrdinalIgnoreCase);
if (openDoor)
{
Console.WriteLine("Ok, opening the door now!");
}
else
{
Console.WriteLine("Ok, leaving the door closed!");
}
Console.Write("\nDone!\nPress any key to exit...");
Console.ReadKey();
}
Output
Here's what it looks like if you run it and give some bad responses...
If you're writing a text adventure for a C# console app, you can find a good description on one possible way of structuring a text adventure game in Usborne's 1980s computer book called "Write Your Own Adveture Programs" which has since been released for free at https://usborne.com/browse-books/features/computer-and-coding-books/
The programming language it uses is old BASIC, so I wouldn't recommend using the code directly (although .NET Console Apps have Console.ReadLine() and Console.WriteLine() which work almost the same as BASICs INPUT and PRINT), but more than that the book talks about how text adventures of the time were structured and the planning that goes into it.
For your specific situation, the old text adventures defined a list of possible verbs (actions) and a list of possible nouns (objects). The user would type either a single verb, or a verb and a noun. The code would match these to the lists, and jump to a specific function (or subroutine) based on the entered verb.
The game loop then prompted the user for an action, accepted some input, processed it in this way, and went back to prompting.
For example:
What should I do now?
north
... would match the "north" verb in the list of verbs, so the program would run the routine to move the player one room north (which would then make sure the player could actually go north from their current location).
What should I do now?
open door
... would split the string on a space, match the "open" verb from the verb list, and the "door" noun from the noun list. The open function would then check where the player was, if there was a "door" there, if the door was already open, etc. then update a "door state" to open, and return a message.
What should I do now?
asdf asdf
... wouldn't match any verb in the list, so the program would respond with "I don't understand how to 'asdf'" or "I don't know what a 'asdf' is."
Of course, there are many approaches to solving this problem and you may already have a design in place that is different from this.
Hope this helps

How the call stack is working in a C# application (Simple example given)

I have never been much into algorithms. Currently I'm unemployed so I decided to learn more about recursion and how to use it. I've been through the basics several times, I know how to solve simple problems like fibonacci numbers and factorial but this is because those problems are most commonly given as examples when someone tries to explain recursion.
However today I started by making again a simple console application for calculating factorial, just to see if I can get something more this time and I come to this situation where I think I have a big leak in my understanding not only for recursion but generally how the stack is working and why things happen the way they do, and since this example is pretty simple I thought that maybe it is a perfect base where I can try to find some new approach to the same problem (how to learn myself to think recursively).
So here it is. For the factorial calculation I made this simple class/method for getting the number from the console. I just didn't felt like making everything static, but no particular reason at all to make it like this, I just did, so I ended up with this class :
class GetUserInput
{
public int GetFactorialNumber()
{
Console.Write("Enter number: ");
int number;
bool result = Int32.TryParse(Console.ReadLine(), out number);
while (!result)
{
Console.WriteLine("Error!");
GetFactorialNumber();
}
return number;
}
}
And in my Main method I have this:
GetUserInput GetNumber = new GetUserInput();
int number = GetNumber.GetFactorialNumber();
So what happens :
I start the program and I enter something that can't be parsed to int for example dfgdf and in y debugger I see this:
I get my Error and I'm asked to enter number again so this time I enter a valid number like 5 and I see this in the debugger :
I get into infinite loop. Even if I enter only valid integers from now on I still see the first invalid call:
and this goes on forever. No matter what I enter from now on if it's invalid the method just stays in the Call stack if the input is valid then the method is removed but I can't never get out of the loop once I've entered an invalid data the first time.
So based on this simple example can you explain what actually happens here. To be honest, at first I thought that this actually will work. I mean - I get a correct input, I get out of the while loop, I hit return and that's all, return, I'm out of this method. Then, when I saw that I get into infinite loop, I tried to explain to myself what's the reason for it and since I have a method that is calling itself I think I've created some kind of recursion, but this is where I get lost - how exactly the stack works and why I am not able to get out of it (in this case but in general too)? Because the main idea is for me to understand how exactly recursion works, can you explain me, how the Call stack works and how exactly my code interacts with it in order to get the result that I've described?
Why not get rid of the recursion here:
public int GetFactorialNumber()
{
Console.Write("Enter number: ");
int number;
while (!Int32.TryParse(Console.ReadLine(), out number))
Console.WriteLine("Error!");
return number;
}
If you want to keep it your way:
public int GetFactorialNumber()
{
Console.Write("Enter number: ");
int number;
while (!Int32.TryParse(Console.ReadLine(), out number))
{
Console.WriteLine("Error!");
** return **GetFactorialNumber(); // Code needs a chance to escape the while
}
return number;
}
bool result = Int32.TryParse(Console.ReadLine(), out number);
while (!result)
{
Console.WriteLine("Error!");
GetFactorialNumber(); // here is the problem, no communication with caller
}
return number;
This input method has no use for recursion and while you could make that work, just do it iteratively.
Using recursion for a Factorial is artificial enough (in production code, use a for() loop).
To understand the behavior, consider your code:
class GetUserInput
{
public int GetFactorialNumber()
{
Console.Write("Enter number: ");
int number;
bool result = Int32.TryParse(Console.ReadLine(), out number);
while (!result)
{
Console.WriteLine("Error!");
GetFactorialNumber();
}
return number;
}
}
The first time in, you enter an invalid result. Then you execute a while loop for !result. Since you passed an invalid parameter, this while loop will loop forever. Inside your loop you are calling GetFactoryalNumber recursively. This will ask you again for another input inside that method, but the results from that will be scoped to that level of the recursion. Nothing is ever going to bubble up to change the outer result to break out of the while loop. Hope this helps your understanding.

Categories