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.
Related
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
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!
I have seen a few other posts very similar to this one, but the answers they give are not correctly answering the question. Sorry if there is something hidden away that I couldnt find...
I want to use Console.WriteLine() to print something above my current Console.ReadLine(), for example, my app prints "Hello world" and starts a thread that (in 5 seconds) will print "I just waited 5 seconds" above the line where I need to input something, like this:
Hello world
Please input something: _
Then 5 seconds will pass and it will look like this:
Hello world
I just waited 5 seconds
Please input something: _
So far I've tried using Console.SetCursorPosition(0,Console.CursorTop - 1) but this just prints over the line "Please input something: _" and if I use Console.CursorTop - 2 instead it crashes saying "[2] Out of range" (no idea why this is) and if I use Console.CursorTop - 2 it prints under "Please input something: _"... so my question is how do I print something ABOVE the line "Please input something: _"
Just moving the cursor is not good enough, the problem is that you are inserting text. That is possible, the Console.MoveBufferArea() method gives you access to the underlying screen buffer of the console and lets you move text and attributes to another line.
There are a couple of tricky corner-cases. One you already found, you have to force the console to scroll if the cursor is located at the end of the buffer. And the timer is a very difficult problem to solve, you can only really do this correctly if you can prevent Console.ReadLine() from moving the cursor at the exact same time that the timer's Elapsed event inserts the text. That requires a lock, you cannot insert a lock in Console.ReadLine().
Some sample code you can play with to get you there:
static string TimedReadline(string prompt, int seconds) {
int y = Console.CursorTop;
// Force a scroll if we're at the end of the buffer
if (y == Console.BufferHeight - 1) {
Console.WriteLine();
Console.SetCursorPosition(0, --y);
}
// Setup the timer
using (var tmr = new System.Timers.Timer(1000 * seconds)) {
tmr.AutoReset = false;
tmr.Elapsed += (s, e) => {
if (Console.CursorTop != y) return;
int x = Cursor.Left;
Console.MoveBufferArea(0, y, Console.WindowWidth, 1, 0, y + 1);
Console.SetCursorPosition(0, y);
Console.Write("I just waited {0} seconds", seconds);
Console.SetCursorPosition(x, y + 1);
};
tmr.Enabled = true;
// Write the prompt and obtain the user's input
Console.Write(prompt);
return Console.ReadLine();
}
}
Sample usage:
static void Main(string[] args) {
for (int ix = 0; ix < Console.BufferHeight; ++ix) Console.WriteLine("Hello world");
var input = TimedReadline("Please input something: ", 2);
}
Note the test on the Console.Top property, it ensures that nothing goes drastically wrong when the user typed too much text and forced a scroll or if Console.ReadLine() completed at the exact same time that the timer ticked. Proving that it is thread-safe in all possible cases is hard to do, there will surely be trouble when Console.ReadLine() moves the cursor horizontally at the exact same time that the Elapsed event handler runs. I recommend you write your own Console.ReadLine() method so you can insert the lock and feel confident it is always safe.
You can use carriage-return (\r, or U+000D) to return the cursor to the start of the current line, and then overwrite what's there. Something like
// A bunch of spaces to clear the previous output
Console.Write("\r ");
Console.WriteLine("\rI just waited 5 seconds");
Console.Write("Please input something: ");
However, if the user has started typing already this won't work anymore (as you may not overwrite all they have typed, and they will lose what they've typed on the screen, although it's still there in memory.
To properly solve this you actually need to modify the console's character buffer. You have to move everything above the current line one line up, and then insert your message. You can use Console.MoveBufferArea to move an area up. Then you need to save the current cursor position, move the cursor to the start of the line above, write your message, and reset the cursor position again to the saved one.
And then you have to hope that the user doesn't type while you're writing your message, because that would mess things up. I'm not sure you can solve that while using ReadLine, though, as you cannot temporarily lock something while ReadLine is active. To properly solve that you may have to write your own ReadLine alternative that reads individual keypresses and will lock on a common object when writing the resulting character to avoid having two threads writing to the console at the same time.
the thing I'm having the most trouble with is understanding the assignment here. I don't know if it's the fact if it's worded weird or that I'm just stupid. I'm not asking for you to do my assignment for me I just want to know if someone would explain what it's asking for.
UPDATE: apparently I now have to use enum on this so now I'm screwed
Please post the content of the question in your post, i.e. copy and past the text.
Secondly, break it down into sections.
1) You must write a program called IntArrayDemo.
2) The program must contain an array that stores 10 Integers (int).
int[] valueArray = new int[10] {1,2,3,4,5,6,7,8,9,10 };
3) The program will run until a sentinal value is entered (i.e. you type something that causes the program to quite, say 'q' or '-1').
while (Console.ReadKey().Key != ConsoleKey.Q) {
ConsoleKey k = Console.ReadKey().Key;
//Check the key here
}
4) The program will have 3 options -
4.1) View the entire array of integers from 0 to 9 (i.e. forwards)
4.2) View the entire array of integers from 9 to 0 (i.e. backwards)
4.3) View a specific location (i.e. you enter a number from 0 to 9, and you are shown the value at that point in the array.
You will need to display some sort of menu on the screen listing the options.
For each of the parts where you need to show the content of the array, use a for loop. While loops, or ForEach loops should never be used of you have a fixed number of things to iterate over.
"I don't know if it's the fact if it's worded weird or that I'm just stupid"
In this case, I'm not sure either of those options is accurate. Programming questions are worded quite carefully to force you to think about breaking the task into sections.
In professional programming, you will get all sorts of weirdly worded questions about how something can be done, and you must break down the problem into steps and solve each one.
It's easy to feel a little overwhelmed when you get a single paragraph with a lot of information in it, but breaking it down makes it much more manageable.
Always start with what you know for certain has to be done - in this case, the program must be called IntArrayDemo, so that's a good starting point.
'that stores an array of 10 integers' - good, more information! The program must have an array, which stores ints, and can hold 10 values.
We can infer from this (knowing that arrays start from 0) that our array must count from 0 to 9.
Enums
You mention that you need to use enums. Enums are just a data type, which you can define yourself.
Supposing you were writing a server program, and needed to easily see what state it was in.
The server can be in the following states at any time - Starting, Running, Stopping, Stopped.
You could use a string easily enough - String state = "Starting" would do the trick, but a string can hold any value.
As the server HAS to be in one of those states, an enum is better, as you can specify what those states are.
To declare an enum, you create it as follows...
enum SERVER_STATE { Starting, Running, Stopping, Stopped };
Then to use it....
SERVER_STATE CurrentServerState = SERVER_STATE.Stopped;
if (CurrentServerState == SERVER_STATE.Running) {
//Do something here only if the enum is set to 'Running'
}
If you wanted to use an enum to decide which option was chosen, you would need to do the following.
1) Get some text of the keyboard (the example using ReadChar above shows you how to do that)
2) Set an enum value based on what was entered
enum ACTION = { ListValuesForward, ListValueBackward, ListSpecificValue };
ACTION WhichOption;
//Our ConsoleKey object is called 'k', so....
if (k == ConsoleKey.F) {
WhichOption = ACTION.ListValuesForward;
}
if (WhichOption == Action.ListValuesForward) {
//Print out the array forwards
}
Knowing that we have an array, that counts from 0 to 9, we can work out that the best loop here is a for loop, as it's controlled by a counter variable.
If you always break a problem down like this, it becomes a lot less daunting.
Hopefully, this should explain the question clearly enough to get you started.
I'm a student and I got a homework i need some minor help with =)
Here is my task:
Write an application that prompts the user to enter the size of a square and display a square of asterisks with the sides equal with entered integer. Your application works for side’s size from 2 to 16. If the user enters a number less than 2 or greater then 16, your application should display a square of size 2 or 16, respectively, and an error message.
This is how far I've come:
start:
int x;
string input;
Console.Write("Enter a number between 2-16: ");
input = Console.ReadLine();
x = Int32.Parse(input);
Console.WriteLine("\n");
if (x <= 16 & x >= 2)
{
control statement
code
code
code
}
else
{
Console.WriteLine("You must enter a number between 2 and 16");
goto start;
}
I need help with...
... what control statment(if, for, while, do-while, case, boolean) to use inside the "if" control.
My ideas are like...
do I write a code that writes out the boxes for every type of number entered? That's a lot of code...
..there must be a code containing some "variable++" that could do the task for me, but then what control statement suits the task best?
But if I use a "variable++" how am I supposed to write the spaces in the output, because after all, it has to be a SQUARE?!?! =)
I'd love some suggestions on what type of statements to use, or maybe just a hint, of course not the whole solution as I am a student!
It's not the answer you're looking for, but I do have a few suggestions for clean code:
Your use of Int32.Parse is a potential exception that can crash the application. Look into Int32.TryParse (or just int.TryParse, which I personally think looks cleaner) instead. You'll pass it what it's parsing and an "out" parameter of the variable into which the value should be placed (in this case, x).
Try not to declare your variables until you actually use them. Getting into the habit of declaring them all up front (especially without instantiated values) can later lead to difficult to follow code. For my first suggestions, x will need to be declared ahead of time (look into default in C# for default instantiation... it's, well, by default, but it's good information to understand), but the string doesn't need to be.
Try to avoid using goto when programming :) For this code, it would be better to break out the code which handles the value and returns what needs to be drawn into a separate method and have the main method just sit around and wait for input. Watch for hard infinite loops, though.
It's never too early to write clean and maintainable code, even if it's just for a homework assignment that will never need to be maintained :)
You do not have to write code for every type of number entered. Instead, you have to use loops (for keyword).
Probably I must stop here and let you do the work, but I would just give a hint: you may want to do it with two loops, one embedded in another.
I have also noted some things I want to comment in your code:
Int32.Parse: do not use Int32, but int. It will not change the meaning of your code. I will not explain why you must use int instead: it is quite difficult to explain, and you would understand it later for sure.
Avoid using goto statement, except if you were told to use it in the current case by your teacher.
Console.WriteLine("\n");: avoid "\n". It is platform dependent (here, Linux/Unix; on Windows it's "\r\n", and on MacOS - "\n\r"). Use Environment.NewLine instead.
x <= 16 & x >= 2: why & and not ||?
You can write string input = Console.ReadLine(); instead of string input; followed by input = Console.ReadLine();.
Since it's homework, we can't give you the answer. But here are some hints (assuming solid *'s, not white space in-between):
You're going to want to iterate from 1 to N. See for (int...
There's a String constructor that will allow you to avoid the second loop. Look at all of the various constructors.
Your current error checking does not meet the specifications. Read the spec again.
You're going to throw an exception if somebody enters a non-parsable integer.
goto's went out of style before bell-bottoms. You actually don't need any outer control for the spec you were given, because it's "one shot and go". Normally, you would write a simple console app like this to look for a special value (e.g., -1) and exit when you see that value. In that case you would use while (!<end of input>) as the outer control flow.
If x is greater or equal to 16, why not assign 16 to it (since you'll eventually need to draw a square with a side of length 16) (and add an appropriate message)?
the control statement is:
for (int i = 0; i < x; i++)
{
for ( int j = 0; j < x; j++ )
{
Console.Write("*");
}
Console.WriteLine();
}
This should print a X by X square of asterisks!
I'ma teacher and I left the same task to my students a while ago, I hope you're not one of them! :)