Is this behavior due to possible async? - c#

Salutations,
I am fairly new to C#, I feel comfortable with Java, and thus I feel decently comfortable with C# (massive fan of its LINQ and SQL syntax). Anywho, I am however a total novice to asynchronous calls, and I was wondering if the following behavior is related to this.
So in my code I have the following:
string sentence;
Console.WriteLine("Enter your sentence: {0}", sentence = Console.ReadLine());
Console.WriteLine("Sentence is: {0}", sentence);
Console.ReadKey();
It is very simple, I was just trying to see if I could insert the reading of the input within the same prompt that asks for it. However, what I notice is that the code runs, but it is a blank screen, I can type my input and then it would display what I typed, and wait for a key click in order to close the CMD window.
What I was wondering is the following: Is this a sort of async behavior -- if not, what is it then? And if so, is it possible to have the ReadLine() within the same Console.WriteLine() or do I have to have them as two separate lines as one would normally do?

There is nothing about asynchronous here.
The first Console.WriteLine requires its parameter(s) to get ready before its own execution. In other words, Console.ReadLine has to execute before the first Console.WriteLine. That is where the blank screen come from.
Just write as
Console.WriteLine("Enter your sentence: ");
sentence = Console.ReadLine()
Console.WriteLine("Sentence is: {0}", sentence);
or in "the same line"
Console.WriteLine("Enter your sentence: ");
Console.WriteLine("Sentence is: {0}", Console.ReadLine());

Synchronous and Asynchronous is not the concern here, just syntax error try
Console.WriteLine("Enter your sentence: ");
Console.WriteLine("Sentence is: {0}", Console.ReadLine());

Related

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!

Console pause c#

In this code
Console.Write("Enter any number from 0 to 9:");
int k = Console.Read();
Console.Write("The ASCII code for it is:");
Console.WriteLine(k);
Console.Read();
after I input a number my console close instantly.
If I write this code
Console.Write("Enter any string:");
string k = Console.ReadLine();
Console.Write("Your string is:");
Console.WriteLine(k);
Console.Read();
my console stops so I can see what I wrote.
Why is that happening?
Try using the following instead of Console.ReadLine();
Console.ReadKey();
This will wait for your console to input any key before closing.
ReadLine, Read etc. should work but you can also run it via Ctrl-F5 instead, which will keep the window open until you hit a key. Or remove the ReadLine at the end completely if you just want it to close.
Note Ctrl-F5 is running without debugging. If you're after breakpoints don't do this.
Although with your code you're only going to going to get the behaviour you expect from the .Read on line 2.
num=Console.Read();
I think it will be the ASCII code for the first 'character' of your number i.e. if you enter 322 it will just read 3 and the ASCII for 3 is 51, which will be what is assigned to num.

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.

Adding a command line input for testing a method in C#

I am writing a program in a C# Console Application and within some of the methods I have Console.ReadLine() and Console.WriteLine(). I want to know how to give the input within a Test Case.
Example:
Console.WriteLine("Enter account number: ");
accountNumber = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter name: ");
cStringName = Convert.ToString(Console.ReadLine());
name = cStringName;
Console.WriteLine("Enter balance: ");
balance = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter Date: ");
dateCreated = Convert.ToString(Console.ReadLine());
So basically the method returns a bool saying if an account was created or not. In my test case I want to be able to call this method but in order for it to execute I need to set accountNumber, name, balance, and date. Is there some sort of way of doing this? Or is the best way just to add parameter to the method(which i prefer not to do)?
Rewrite the method so that it takes a couple of Stream as parameters. Then when you call it in the real program, send in Console.Out and Console.In as parameters. When calling from your test case, send in some memory streams instead.
When writing this kind of methods and you want to test them, they should not depend directly on the console, but rather on an abstract stream. Then you use dependency injection (e.g. passing in the streams as parameters) to be able to substitute the console for a memory stream when testing.

Categories