Why does the console close after my last input? - c#

My program allows the user to put in 20 prices and to display the average of those values. Why does the console close after I enter my last input? Below is the code I'm running:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace machineproblem4
{
class Program
{
static void Main(string[] args)
{
int sum = 0;
double average = 0;
Console.WriteLine("\t\t\t INPUT PRICES \n");
int[] price = new int[20];
Console.WriteLine("\t\t\t Please enter 20 prices \n");
for (int ctr = 0; ctr < 20; ctr++)
{
Console.Write("Enter price {0} : ", ctr + 1);
price[ctr] = Convert.ToInt32(Console.ReadLine());
}
// [...calculate sum...]
//average
Console.WriteLine("\n----------------------------");
Console.WriteLine("||average of the prices||");
average = sum / 20;
Console.WriteLine("average of the prices: {0}", average);
//more code that outputs statistics about the inputs
//exit
//Edit: This is what fixed my problem
Console.WriteLine("press any key to exit ..");
Console.ReadKey();
}
}
}

use Console.Readline();
Read(), ReadLine() and ReadKey() are basically static methods, and they comes under the Console class. That's why we use these methods like:
Console.Read():-- method accept the String and return the integer.
Console.ReadLine():--method accept the String and return string .
Console.ReadKey():--method accept the Character and also return Character.
That's why we mostly use the Console.ReadKey() method, for come back to source code from output window .
Because when we only press the character we directly come on source code. If you will use the Console.Read() and Console.ReadLine method then
you need to press Enter, come back to the source code rather then any character.

You can place a Console.Read() at the last statement. You can also place a breakpoint at your last statement

Generally, it is not a good idea to wait for user input from a console application. This is okay for debugging, but not definitely for release.
So, first find out if your application is in debug or release config using
private static bool IsDebug()
{
object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(DebuggableAttribute), false);
if ((customAttributes != null) && (customAttributes.Length == 1))
{
DebuggableAttribute attribute = customAttributes[0] as DebuggableAttribute;
return (attribute.IsJITOptimizerDisabled && attribute.IsJITTrackingEnabled);
}
return false;
}
Then use,
if (IsDebug())
Console.Readline();
This eliminates the need to edit the code for different build configurations. Alternative is to put a breakpoint and debug the console app, as suggested by #Erwin

Put:
Console.Readline();
at the end of your main function, so it waits until you press enter before it closes.

None of the previous answers actually directly answer the question of why this is happening. The reason why the console is closing after your last input is that the rest of the code runs very quickly and when it reaches the end of your program, the console closes. This is correct behavior and should be expected when running a console application. As the other answers have stated, you can work around this by requiring a final input before closing the console, but that is all it is, a work around.
If you were to output to a text file rather than just the console, you would see that all of the output is generated as you would expect. The console output and close is just too fast for you to see it without some sort of pause in the code.
Additionally, a solution that has not been mentioned yet is to run the project from Visual Studio without debugging, which will automatically output "Press any key to continue..." when it finishes processing before closing the console. That way you can see what it is outputting without extraneous code that you wouldn't want to have in production code.

Related

Program exiting when using String.ToUpper(); on a string that has spaces in it

Let me start off saying that I'm new to C#.
I'm currently in the making of my first command-line application that in it's current state can do two things. One of them is a calculator, for which I need more learning to actually make it work, and the other is a string capitalizer.
I have a string nameCapInput = Console.Readline() that takes in the user input, which then gets analyzed to make sure that no digits are allowed:
using System;
using System.Linq;
namespace First_Console_Project
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("My first ever console application - 2020/2/26\n\n\n");
programSel:
Console.WriteLine("What do you want to do?\n");
Console.WriteLine("1. Calculate Numbers \n2. Capitalize Letters/Strings");
Console.WriteLine("Input your desired action:");
var inputVar = Console.ReadLine();
switch (inputVar)
{
case "1":
//Calculator code goes here
Console.WriteLine("Number 1 succeeded, opening calculator... Stand by");
Console.WriteLine("Calulator Loaded.");
Console.WriteLine("Doesn't work right now. Type \"exit\" to get back to the \"what do you want to do\" page.");
//Code goes here when I have learned the proper methods
calcInput:
var calcInput = Console.ReadLine();
if (calcInput == "exit")
{
goto programSel;
} else
{
Console.WriteLine("Unknown command. Type \"exit\" to get back to the \"what do you want to do\" page.");
goto calcInput;
}
case "2":
Console.WriteLine("Loading string capitalizer...");
Console.WriteLine("Type any string made of letters only without spaces, because if you use spaces, the program will exit. The output will make them all uppercase. Type \"exit\" to get back to the \"what do you want to do\" page.");
inputCap:
string nameCapInput = Console.ReadLine();
bool containsInt = nameCapInput.Any(char.IsDigit);
bool isMadeOfLettersOnly = nameCapInput.All(char.IsLetter);
if (nameCapInput == "exit")
{
goto programSel;
}
else if (containsInt)
{
Console.WriteLine("You can't capitalize numbers. Use letters only. Try again.");
goto inputCap;
}
else if (isMadeOfLettersOnly)
{
string upper = nameCapInput.ToUpper();
Console.WriteLine($"The uppercase version of your entered text is: {upper}");
goto inputCap;
}
break;
}
}
}
}
Now, everything works fine and it capializes everything I put into it except strings with spaces in them. When I type in a string with spaces in it, the program just exits with code 0. I'm not very good at C# yet, so I don't really know where to go from here. Any help is appreciated.
Every time I learn something new in C#, I try to implement it into my projects, so I can actually learn how to implement it to know when and how to use what I learned. This is an example for that.
EDIT: Added the rest of the code.
Thank you all very much. There's two things I have learned here:
goto is a bad habit
I absolutely need to start learning to debug my own code.
The crux of your problem is that you are only checking if the input contains letters (not spaces). An easy fix is to change your LINQ a bit.
bool isMadeOfLettersOnly = nameCapInput.All(c => char.IsLetter(c) || char.IsWhiteSpace(c));
So now input with letters or spaces will be considered valid.
In addition, your use of goto is a very bad idea. Generally there should never be any reason to use goto.
To fix this, use a while loop and a method:
public static void Main()
{
bool exit = false;
do {
exit = ProcessInput();
}
while(!exit);
}
private static bool ProcessInput()
{
string nameCapInput = Console.ReadLine();
bool containsInt = nameCapInput.Any(char.IsDigit);
bool isMadeOfLettersOnly = nameCapInput.All(c => char.IsLetter(c) || char.IsWhiteSpace(c));
if (nameCapInput.Equals("exit", StringComparison.CurrentCultureIgnoreCase))
{
return true; //exiting so return true
}
else if (containsInt)
{
Console.WriteLine("You can't capitalize numbers. Use letters only. Try again.");
}
else if (isMadeOfLettersOnly)
{
string upper = nameCapInput.ToUpper();
Console.WriteLine("The uppercase version of your entered text is: {0}", upper);
}
return false; //no exit, so return false
}
This is just a quick refactor, you could make it better.
Fiddle here
Check the documentation: https://learn.microsoft.com/en-us/dotnet/api/system.char.isletter?view=netframework-4.8
Based on the documentation of the IsLetter function, the space is not included in the return true cases.
I would suggest that you use regular expressions for this or change your last case to
else if (!containsInt)
{
var upper = nameCapInput.ToUpper();
Console.WriteLine($"The uppercase version of your entered text is: {upper}");
goto inputCap;
}
Also check the documentation of goto: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/goto
The goto statement transfers the program control directly to a labeled statement.
A common use of goto is to transfer control to a specific switch-case label or the default label in a switch statement.
The goto statement is also useful to get out of deeply nested loops.
You are not in any such case, so you shouldn't use it.

How to make the console wait but then continue without pressing a Key?

I'm fairly new to this community however I'm studying at college on an IT course. And we have been set an assignment to come up with our very own console code. I thought it would be cool and somewhat unique if I program a funny hacker like typerwiter. I have managed to get it to type by itself and be automated so the user doesn't have to do anything for the program to work.
This project is completely experimental and more of a challenge to expand my knowledge and skill however I would like to find out and know how to:
1; Make the program wait.
So for example where my text reads "Initiating decryption..." I would like it to wait, let's say 3 seconds and then carry on. To make it seem as if it's actually processing some sort of data.
2; Make it work on commands.
So I have basic knowledge on switches and if commands. However, I'd like to learn more in-depth on how it all works.
So say in my last text "Would you like to proceed?" I wanted a choice to either close down the console or to carry on with the imaginary decryption. How could I achieve this by then being able to carry on making more text and options for the user to participate?
{
Console.ForegroundColor = ConsoleColor.Green;
var myString = "Initiating decryption..." + Environment.NewLine + "> 248,604 possible combinations found" + Environment.NewLine + "<-> Would you like to proceed?";
foreach (var character in myString)
{
Console.Write(character);
Thread.Sleep(60);
}
Console.WriteLine();
Console.ReadLine();
}
}
you can use a Simple if statement and and while bucle to execute the same all time.
while(true) {
System.Threading.Thread.Sleep(3000); // to waiting 3 seconds
Console.WriteLine("Would you like to proceed ? (Y/N)");
var option = Console.ReadKey();
if (option.ToString().ToUpper() == "N"){
Environment.Exit(0);
}
}
If I understand well you want to ask a question to the user, then do something depending on his input.
A basic orientation would be :
Console.WriteLine("Would you like to proceed ? (Y/N)");
string choice = Console.ReadLine();
if (choice == "y")
{`enter code here`
do something
}
else
{
do something else
}

Getting output data from console application

I am new to .NET programming. I referred to a tutorial while creating this project. I have a dll file that does add and subtract functions:
ClassLibraryDll.dll
public class MathClass
{
//method for Addition
public static long Add(long num1, long num2)
{
return num1 + num2;
}
//method for Subtraction
public static long Sub(long num1, long num2)
{
return num1 - num2;
}
}
I have an .NET Console Application which has a program class which will make reference to the dll file and will use the functions from the dll file and take in two integers as input and display an output according to the function chosen.
Program.cs
using ClassLibraryDll;
class Program
{
static void Main(string[] args)
{
MathClass.Add(10, 10);
Console.WriteLine("Calling methods from ClassLibraryDLL:");
if (args.Length != 2)
{
Console.WriteLine("Usage: TestCode <num1> <num2>");
return;
}
long num1 = long.Parse(args[0]);
long num2 = long.Parse(args[1]);
long sum = MathClass.Add(num1, num2);
long substract = MathClass.Sub(num1, num2);
Console.WriteLine("{0} + {1} = {2}", num1, num2, sum);
Console.WriteLine("{0} * {1} = {2}", num1, num2, substract);
}
}
The output I am suppose to get assuming 1 and 1 are entered as command line args:
Calling methods from ClassLibraryDll:
1 + 1 = 2
1 - 1 = 0
I am unsure how to get the output from the console application. When I run the console application, I am unable to input any integers.
enter image description here
Someone please help me. Thank you so much in advance.
I think you're looking for the Console.ReadLine method, which waits for the user to input a line of text.
The command line args are used mainly when starting an application automatically from another application, or from a shortcut link etc, and I think are the wrong option for this kind of problem.
Hope this helps!
Looks like you're trying to call run the 'executable' file without the required arguments.
To run an executable file with arguments, you need to do the following.
1) Start the command prompt.
(Windows Key + R -> cmd)
2) Change current directory to your Console Application projects 'Debug' folder
(Eg., cd C:\YourProjectFolder\bin\debug)
3) Enter name of executable with arguments
(Eg., C:\YourProjectFolder\bin\debug>YourExecutableName 1 1)
If you insist on running from Visual Studio, you need to open your project's properties, click the Debug tab and enter your numbers as Command line arguments. You will not be able to see the results unless you add a Console.ReadLine() at the end of your program. I often do this:
if (System.Diagnostics.Debugger.IsAttached)
{
Console.Write("Press <Return>");
Console.ReadLine();
}
If run from inside Visual Studio, if will wait for a Carriage Return, otherwise not.

C#/.NET console applications that behave like normal Unix tools

This question is regarding designing console applications in .NET that behave like normal Unix tools. The basic fundamental of Unix tools is that they can be chained together with 1 tool being able to take input from any compatible stream and giving output to any compatible stream.
If I'm writing console applications in .NET for Windows, what are the general things I need to follow for my tools to be of the same type?
"Do only one thing" is definitely one, but there are more:
Do only one thing and do it well
Output nothing on success (other than the result, of course)
Use stdin for the input, stdout for the output, and stderr for errors
Use non-zero exit codes to communicate failure
With this in mind, here's what is, in my opinion, a more "unixy" "to-uppercase" program in C#:
using System;
class Program
{
static int Main(string[] args)
{
try
{
var buf = new char[4096];
while (true)
{
int read = Console.In.Read(buf, 0, buf.Length);
if (read == 0)
break;
for (int i = 0; i < read; i++)
buf[i] = char.ToUpper(buf[i]);
Console.Out.Write(buf, 0, read);
}
return 0;
}
catch (Exception e)
{
Console.Error.WriteLine("ERROR: " + e.Message);
return 1;
}
}
}
Like a typical unixy program, you can run it without arguments and then it will be interactive, allowing you to type input manually on the console, terminated with Ctrl+Z, printing output whenever it receives a chunk of your input. Or you could pass it a file to process: uppercase.exe <input.txt and it will print the output to the console. Or you could redirect the output to a file too. Or you could pipe the input into it. Etc.
The main principle behind *nix tools is do one thing, and do it well.
Let's say I set out to create a *nix style tool that converted the input to uppercase. It's a trivial example, but that allows me to post the whole program here.
Here's the source code:
using System;
using System.Diagnostics.Contracts;
namespace Upperc {
class Program {
static void Main(string[] args) {
var input = Console.ReadLine();
Contract.Assert(input != null);
Console.WriteLine(input.ToUpperInvariant());
}
}
}
I took advantage of the fact that Console methods handle input and output and the standard streams. Example usage is:
> type example.txt | Upperc.exe > uppercased.txt
The input file is a plain text file:
example text file before processing
and the output file:
EXAMPLE TEXT FILE BEFORE PROCESSING

Writing to the console from a method .NET 4.0

The following is a short clock program from the book "programming in the key of c#". I'm not familiar with the Timers library at all so some of this syntax I don't really get. What I want to understand and I don't is the line Console.Write(str) in the method in this little program. How does Main know what to print to the console? Is it the empty Console.WriteLine() call that makes the time print out every second? When I'm reading about these concepts it seems easy after the fact to understand what's going on. Based on what I've asked, what are the things about C# that I don't really understand yet?
using System;
using System.Timers; // Requires System.dll
class Clock
{
static int iStringLength;
static void Main()
{
Console.WriteLine("Press Enter to end program");
Console.WriteLine();
Timer tmr = new Timer();
tmr.Elapsed += new ElapsedEventHandler(TimerHandler);
tmr.Interval = 1000;
tmr.Start();
Console.ReadLine();
tmr.Stop();
}
static void TimerHandler(object obj, ElapsedEventArgs eea)
{
Console.Write(new String('\b', iStringLength));
string str = String.Format("{0} {1} ",
eea.SignalTime.ToLongDateString(),
eea.SignalTime.ToLongTimeString());
iStringLength = str.Length;
Console.Write(str);
}
}
Main() doesn't print anything to the console, except for the initial blank line.
Console.Write() in the TimerHandler() callback runs every second and prints the time.
str contains the value of the string after the String.Format() function is called. That function is documented here: http://msdn.microsoft.com/en-us/library/b1csw23d.aspx
In your code, the {0} is replaced by the formatted representation of eea.SignalTime.ToLongDateString(), and the {1} is replaced by a formatted representation of eea.SignalTime.ToLongTimeString().
So to answer
What I want to understand and I don't is the line Console.Write(str)
in the method in this little program. How does Main know what to print
to the console?
the answer is "It writes whatever the String.Format() function has determined the value of "str" is in this line:"
string str = String.Format("{0} {1} ",
eea.SignalTime.ToLongDateString(),
eea.SignalTime.ToLongTimeString());
The WriteLine() function just prints an empty line and really has nothing to do with the string that shows the date/time as you asked.
For the record, Console.Write and Console.Writeline are documented here and here, respectively.
Console.WriteLine() without any parameters does exactly what it sounds like, just prints out an empty line (newline).
Writes the current line terminator to the standard output stream.
Console.WriteLine(xxx) with any parameter prints the parameter on a line, followed by a new line.
Writes the specified data, followed by the current line terminator, to
the standard output stream.
In your TimerHandler method, you are using Console.Write(xxx), which just prints the text representation of the parameter, without a newline.
Writes the text representation of the specified object to the standard
output stream.

Categories

Resources