Trying to fix reading from file C# - 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.

Related

C# Check for key press without delay (Console application) [duplicate]

This question already has answers here:
Listen on ESC while reading Console line
(6 answers)
Closed 1 year ago.
first time posting here, so I apologise in advance in case I miss something important, please let me know if that's the case!
I'm writing a console application that has a menu with several different options in different layers, and I'm trying to make a function that will, at any time as the user works in these menus, notice if the Esc key is pressed. To make my code less cluttered I wrote a separate method that I can simply call at any point when I'm asking for input (like a choice, or entering information into a form, or such).
The problem I have is that it always cancels out the first key press. If a user enters a number to move in the menu, the number doesn't get entered, if they enter a name into a form the first letter is missing etc.
Is there a way around this?
The code currently looks like this;
public static void checkForEsc()
{
ConsoleKeyInfo key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Escape)
{
switch (currentUserisAdmin)
{
case true:
Menu.AdminMenu();
break;
case false:
Menu.CustomerMenu();
break;
}
}
}
Thanks in advance :)
Edit:
Might be worth adding that the code where this snippet gets called looks something like this, with very small variations;
Console.WriteLine($"1. Add a user\n2. Remove a user \n3. See user info \n \n9. Cancel");
Program.checkForEsc();
int response2 = CheckIfResponseInt(Console.ReadLine());
You need to write your own line editor instead of using Readline. It's described in the link below. You may need to add support for other control keys such as backspace or add a check that only numeric keys are being pressed.
Listen on ESC while reading Console line

Why do I get System.String [ ] in my code while debugging?

I am on my final project in c# for beginners, but I can't seem to get my list to work properly. It also closes automatically after being 'filled' with orders.
class Burgare
{
private string[] hamburger = new string[24];
private int no_burger = 0;
public void add_burger()//Ordering of burgers
{
Console.Clear(); //Clears console to make it look cleaner
while (true)
{
int Burger_option = 0;
do
{
Console.WriteLine("");// The options user can choose from
Console.WriteLine("Please choose burgers from our menu:");
Console.WriteLine("-------Burgers--------");
Console.WriteLine("1 Original One 109");
Console.WriteLine("2 Pig & Cow 109");
Console.WriteLine("3 Spice & Nice 109");
Console.WriteLine("4 Green One 109");
Console.WriteLine("0 Go back to main menu");
Console.WriteLine("----------------------");
Console.WriteLine("");
try //Making sure the user only picks what is on the menu
{
Burger_option = int.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("You can only choose what is on the menu!");
}
switch (Burger_option) //Depending on the number user presses on keyboard different burgers will be added to order
{
case 1:
Console.WriteLine("You've added the Original One to your order");
Console.WriteLine("If you're done press 0 to go back to the main menu");
hamburger[no_burger] = "Original One";
break;
case 2:
Console.WriteLine("You've added the Pig & Cow to your order");
Console.WriteLine("If you're done press 0 to go back to the main menu");
hamburger[no_burger] = "Pig & Cow";
break;
case 3:
Console.WriteLine("You've added the Spice & Nice to your order");
Console.WriteLine("If you're done press 0 to go back to the main menu");
hamburger[no_burger] = "Spice & Nice";
break;
case 4:
Console.WriteLine("You've added the Green One to your order");
Console.WriteLine("If you're done press 0 to go back to the main menu");
hamburger[no_burger] = "Green One";
break;
case 0: //Sends user back to main menu
Run();
break;
}
no_burger++; //Adds burger
} while (no_burger != 0);
if (no_burger <= 25) //Maximum number of orders
{
Console.WriteLine("The restaurant can't take more than 24 orders of burgers at the time");
Run(); //Sends user back to main menu when the order is over 24
}
}
}
public void print_order()
{
Console.WriteLine("-Your current order-");
foreach (var burger in hamburger) //Showing a list of what is in the order
{
Console.WriteLine(hamburger);
if (burger != null)
Console.WriteLine(burger);
else
Console.WriteLine("Empty space"); //Making empty space to show where you can add more burgers
}
}
After entering 24 orders I get the error "System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'" I've looked around a bit but still don't really understand how to fix my code. I'd like for it to return to the main menu after telling the user the order is full.
For my second problem the System.String [] problem, it appears when I enter the 'print_order'. It shows itself as
System.String []
Empty space
System.String []
Empty space
And so on. If possible I'd like to either remove it completely or at least replace it with 1,2,3...etc.
First off, please only post one question per question; you've described many problems here, but only actually asked one question. If you have multiple questions, post multiple questions.
Why do I get System.String[] in my code while debugging?
C# by default gives the name of the type when you print it out, and you're printing an array of strings. To turn an array of strings into a string, use the Join method of the string type. Be careful to not confuse it with the Join extension method on sequences.
It also closes automatically after being 'filled' with orders.
When a console program's control reaches the end of Main, it terminates the program. If you want something else to happen, write code that indicates what you'd like to happen.
After entering 24 orders I get the error "System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'" I've looked around a bit but still don't really understand how to fix my code. I'd like for it to return to the main menu after telling the user the order is full.
You've reserved space for 24 things, and you've tried to access the 25th thing. That's a fatal error. Don't do that. You are required to detect that situation and prevent it.
If you want it to return to the main menu after telling the user the order is full then write code to do that. How? Since apparently the main menu is a thing that can happen more than once, you'll want to put it in a loop. You've already written two loops; put more stuff in the loops!
While we're looking at your code, some more good advice:
Start using the conventions of the C# language now. You wrote Console.WriteLine and then made a method print_order. Follow the pattern set by the designers of the framework, not something you've just made up on your own. Types and methods should be CasedLikeThis.
Never put an int.Parse in a try-catch, ever. That's what int.TryParse is for!
Your program has a bug; what happens if someone types in, say, 7? Handle that case!
You never actually check to see how many items you've added inside your do...while loop - you only check this after the loop is complete. That's why it crashes when you try to add the 25th item.
Move the logic to handle this inside your do...while loop and you won't get the exception anymore.
Also, your array only has room for 24 items, but I assume that you meant for it to be 25.
Also, since you're new to programming, you may want to look at #Eric Lppert's helpful article on debugging techniques - it'll save you a lot of time. You should also read about how to use a step debugger to diagnose problems.

Asking the user the same question more than once in 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!

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 do I receive and store data input in C#?

Basically I'm still in the starting phase, and I know how to use Console.WriteLine, but I have no idea on how to have it read input from the user.
For example, I'd want a user to be able to type in a pair of numbers, then return the result.
My goal is a program that receives input , then combines them and returns the average.
This is all in Visual C# Express 2008
string input = Console.ReadLine();
that will return you a string of the user's input. Check out MSDN for documentation on the Console class. Also look at the Convert class.
int num = Convert.ToInt32(input);
Good luck new coder.
First create a variable to store the user input, like this:
int variablenameofyourchoice = 0;
Then take input like this and store it in your variable name:
variablenameofyourchoice = int.parse(Console.ReadLine())
Then do whatever you want with that variable. If you want two numbers do this twice.
This is a very general topic with a lot of answers, but Console.ReadLine is one counterpart of Console.WriteLine. It reads a line of text from standard in.
Have a look at Console.ReadLine() or Console.Read() in the MSDN Documentation

Categories