I've created a small application that does a small conversion. At the end of the program I've created a method that allows the user to make another calculation if they press 'r'. All I want it to do is if they press r, take them back to the beginning of Main, else terminate program. I do not want to use goto. This is what I've got so far, and the error I'm getting.
http://puu.sh/juBWP/c7c3f7be61.png
I recommend you use another function instead of Main(). Please refer to the code below:
static void Main(string[] args)
{
doSomething();
}
public static void WouldYouLikeToRestart()
{
Console.WriteLine("Press r to restart");
ConsoleKeyInfo input = Console.ReadKey();
Console.WriteLine();
if (input.KeyChar == 'r')
{
doSomething();
}
}
public static void doSomething()
{
Console.WriteLine("Do Something");
WouldYouLikeToRestart();
}
A while loop would be a good fit, but since you say the program should run and then give the user the option to run again, an even better loop would be a Do While. The difference between while and Do While is that Do While will always run at least once.
string inputStr;
do
{
RunProgram();
Console.WriteLine("Run again?");
inputStr = Console.ReadLine();
} while (inputStr == "y");
TerminateProgram();
In your case, you want to repeat something so of course you should use a while loop. Use a while loop to wrap all your code up like this:
while (true) {
//all your code in the main method.
}
And then you prompt the user to enter 'r' at the end of the loop:
if (Console.ReadLine () != "r") {//this is just an example, you can use whatever method to get the input
break;
}
If the user enters r then the loop continues to do the work. break means to stop executing the stuff in the loop.
Related
I'm pretty new to C# and coding in general so it is hard for me to explain
and this might be something simple.
The program I am trying to make changes values in the game (Assault Cube).
Without the inner while loops, it just changes the values, I would like them to loop.
I have one outer while loop with multiple loops inside.
The inner while loops are there to loop the function but it stops the outer while loop.
I would like multiple inner loops to run along with the outer one.
I have tried what feels like everything. I tried Booleans, Breaks, Returns.
But nothing I have tried has fixed my problem. It may not be because they don't work, it may just be me using them wrong.
while (true) //outer loop
{
Console.Title = "SlavScripts";
int address1 = LocalPlayer + Health;
int address2 = LocalPlayer + Armor;
string Player = "";
Console.WriteLine("---SlavScripts v2.0---");
Console.WriteLine("");
Console.WriteLine("[1] Player Options");
Console.WriteLine("");
string answer = "";
answer = Console.ReadLine();
if (answer == "1")
{
Console.WriteLine("--Player Options--");
Console.WriteLine("");
Console.WriteLine("[1] Godmode");
Console.WriteLine("[2] Armor");
Console.WriteLine("");
Player = Console.ReadLine();
if (Player == "1")
{
Console.WriteLine("Godmode Enabled");
Console.WriteLine("");
while (true)
{
vam.WriteInt32((IntPtr)address1, 6969); //value to loop.
}
}
else if (Player == "2")
{
Console.WriteLine("Infinite Armor Enabled");
Console.WriteLine("");
while (true)
{
vam.WriteInt32((IntPtr)address2, 6969); //value to loop.
}
}
}
}
(full code: https://pastebin.com/bBcBPYs6)
Expected:
I enter the corresponding digit to activate the function
The function that was activated loops, and original text appears which allows me to navigate to another function.
Actual:
I enter the corresponding digit to activate the function.
The function activates and loops, but does not show opening text and disallows my to type further.
Think about what is happening in your code. Each instruction in your code is executing one after the other (superficially thinking - this might not be exactly true at assembly execution level but you get the idea). For example the line if (answer == "1") will only executed when the line before it (that is answer = Console.ReadLine();) completes its execution.
When you create the "outer while loop" (as you called), everything inside the loop will execute 1 instruction at a time following the order they are written and when the last instruction inside the loop is executed, the execution will jump back to the first line of code inside the loop.
If you put another while loop inside the "outer one", and say it will not have an exit condition (by declaring while(true) you are creating a loop that will never stop executing its embedded statements). Therefore when the execution reaches one of these while(true) loops it will be trapped inside them looping its embedded statements forever.
What I described is how instructions are executed. The other part you need to know is what is a thread. You can think of a thread as an isolated machine where every code is executed. When you don't deal with threads directly in your code, the compiler will automatically asks the operating system to create a thread to run your code at - this is usually referred to as the main thread.
So, what you actually need in your code is to inform the operating system to put the execution of each one of those "inner while(true)" loops inside a thread other than the main one and leaving the main thread to execute only code that can sequentially be executed.
You can learn how to use threads in your application here.
And as a side-note: that is probably not what you want to create a loop spinning code every cycle. You should consider pausing the execution inside those "inner loops" by putting the thread that is executing it to sleep for some time each time it iterates through (you can do this by just calling System.Threading.Thread.Sleep(100) - it will pause the thread execution by 100 milliseconds and will save some cpu execution time).
As per your expectation,
Please find the sample code snippet for getting user input continuously - achieved using Task in C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SampleTaskStop
{
class Program
{
static public void SetValue(string address, int value)
{
while (!_cancelled)
{
//vam.WriteInt32((IntPtr)address1, 6969); //value to loop.
}
Console.WriteLine(address + " - completed");
}
static bool _cancelled = false;
static void Main(string[] args)
{
while (true) //outer loop
{
Console.Title = "SlavScripts";
Console.WriteLine("---SlavScripts v2.0---");
Console.WriteLine("");
Console.WriteLine("[1] Player Options");
Console.WriteLine("");
string answer = "";
answer = Console.ReadLine();
_cancelled = false;
if (answer == "1")
{
var acceptUserInput = Task.Factory.StartNew(AcceptUserInput);
acceptUserInput.Wait();
}
}
}
private static void AcceptUserInput()
{
// Task to perform the value setting in the
Task computationTask = null;
Console.WriteLine("Enter Player Input");
Console.WriteLine("1 God Mode");
Console.WriteLine("2 Armour Mode");
Console.WriteLine("Press Esc to cancel");
var key = Console.ReadKey(true);
while (key.Key != ConsoleKey.Escape)
{
if (key.Key == ConsoleKey.D1 || key.Key == ConsoleKey.NumPad1 )
{
Console.WriteLine("Godmode Enabled");
Console.WriteLine("");
_cancelled = true;
if (computationTask != null)
{
computationTask.Wait(new System.Threading.CancellationToken());
}
_cancelled = false;
computationTask = Task.Factory.StartNew(() => SetValue("data1", 6979));
}
else if (key.Key == ConsoleKey.D2 || key.Key == ConsoleKey.NumPad2)
{
Console.WriteLine("Infinite Armor Enabled");
Console.WriteLine("");
_cancelled = true;
if (computationTask != null)
{
computationTask.Wait(new System.Threading.CancellationToken());
}
_cancelled = false;
computationTask = Task.Factory.StartNew(() => SetValue("data2", 6979));
}
key = Console.ReadKey(true);
}
_cancelled = true;
Console.Write("Computation was cancelled");
}
}
}
Thanks to everyone who replied!
Multi-Threading sounds alot harder than it actually is and it also simplified my code alot!
Still have to add Thread.Sleep's :D
Cheers!
New & Improved - pastebin.com/qN7ci0By
I've been trying to make an application that print characters one by one like in old rps. I found out that i need to use Thread.Sleep to do that. I also want the code to stay open instead of closing. Is there any way to do that?
I used Console.Read, Console.ReadLine, and Console.ReadKey. but all of them stop printing what i want after the first character.
{
static void Main(string[] args)
{
string sntnc = "Example";
foreach (char chrctr in sntnc)
{
Console.Write(chrctr);
Thread.Sleep(50)
;
I want the result to be an application that prints character individually and for it to stay open when it finished.
Try the following. When you are inside the foreach loop, your code will keep running and keep your console window open. After the foreach loop, you can call Console.ReadKey(); to keep the console open until a key is pressed. This code will print out the characters one by one with a 50 ms delay between each letter.
public static void Main()
{
string sntnc = "Example";
foreach (char chrctr in sntnc)
{
Console.Write(chrctr);
System.Threading.Thread.Sleep(50);
}
Console.ReadKey();
}
I would like to know how to go from a method back to main. For example, I want to check if number passes a certain criteria; I would perform a test in a different method and if it returns true, I want to continue using that number back in main. How can go from one method to main again in a continuous loop? I tried calling the main method but the program displays a message for error.
The way my project is set out is that a menu appears for the user to enter a postal code. The menu has many options to add, quit, or view their codes. Once they have added their postal code and it is valid, how can I loop it back to main with the menu appearing again, performing the same functions?
Small section from main:
if (decision.Equals("A"))
{
Console.Write("\n");
Console.WriteLine("Please enter your postal code: ");
for (i = 0; i < 1; i++)
{
postalcodez = Console.ReadLine().ToUpper();
if (isValid(postalcodez, i, number, j, num))
{
postalcode[i] = postalcodez;
Console.WriteLine("It worked!");
Console.ReadLine();
}
}
}
Now it goes through the method to check for conditions. If it returns true, how can I make it go back to main?
public static bool isValid(string postalcodez, int i, int number, int j, int num)
{
if (postalcodez.Length > 7 || postalcodez.Length < 7)
{
return false;
}
if (postalcodez[0].ToString().Equals("W") || postalcodez[0].ToString().Equals("Z"))
{
return false;
}
if (postalcodez.Length.Equals(7))
{
if (postalcodez[3].ToString().Equals(" "))
{
return true;
}
else
{
return false;
}
Another question is that how can I make an array so that I can set a condition for a specific character number. Instead of doing this ( where I hard code specific digits) I want it that the 1, 4 and 6th character must be a certain value :
if (postalcodez[1].ToString().Equals(0) || postalcodez[1].ToString().Equals(1) || postalcodez[1].ToString().Equals(2) || postalcodez[1].ToString().Equals(3) || postalcodez[1].ToString().Equals(4))
{
return true;
}
Since this is for school, I can use any special functions to resolve the issue. It has to be very basic.
It seems like you have a bit of a misunderstanding of what Main() actually is. Main() is, in effect, your entire application. Main is the root that everything will flow back to when the current call stack finishes resolving, and if there are no additional statements after that point, Main will complete, and the application will close. When you call methods from Main, when they return a value (if not void), you are then back inside of Main.
Based on what you have stated is your need, here is a very basic example of what will happen - the flow of the code should be reasonably clear:
private static void Main(string[] args)
{
int number = 5;
bool isValid = VerifyNumber(number);
if (!isValid)
Console.WriteLine("Not valid.");
else
Console.WriteLine("Valid.");
Console.ReadKey();
}
private static bool VerifyNumber(int number)
{
return number > 2;
}
Things to take note of:
Since the method being called from Main has an argument, that argument is provided from inside of Main. This means that when the method finishes, Main still has access to that value.
The output of the method is stored so that work can be done inside of Main based on it.
I have just started learning C# and I'm practicing some basic coding in the console application and I'm trying to make a program that adds two integers together by using an infinite loop and a method. But I want to be able to end the loop by pressing escape but the problem is, is when I press any key besides escape after the loop has completed for the first time, the program crashes. It says "Input string was not in a correct format." Any suggestions would be greatly appreciated!
Thanks!
namespace ConsoleApplication2
{
class Program
{
static void Addxy(int x, int y)
{
Console.WriteLine(x+y);
}
static void Main(string[] args)
{
while(true)
{
Addxy(Convert.ToInt32(Console.ReadLine()), Convert.ToInt32(Console.ReadLine()));
ConsoleKeyInfo end;
end = Console.ReadKey();
if (end.Key == ConsoleKey.Escape)
break;
else
{
}
}
}
}
}
You have two Console.ReadLine() before Console.ReadKey(). So the first two inputs should be numerals followed by the Escape key to terminate the program. Remember to press Enter after the first two numeral entry.
You could use break to end the loop, but a more elegant way would be to define a variable that determines if the loop should keep running. Here is my suggestion for your problem:
static void Main(string[] args)
{
bool keepLooping = true;
while (keepLooping)
{
//Do your stuff here
if (Console.ReadKey().Key == ConsoleKey.Escape)
{
keepLooping = false;
}
}
}
or an even shorter version if you prefer that:
static void Main(string[] args)
{
bool keepLooping = true;
while (keepLooping)
{
//Do your stuff here
keepLooping = Console.ReadKey().Key != ConsoleKey.Escape;
}
}
When an exception occurs I want to restart all the processing or start the Main method, after this other method:
public void DisplayMessage(string message) {
Console.WriteLine(message, "Rebuild Log Files");
Console.WriteLine(" Press Enter to finish, or R to restar the program...");
string restart = Console.ReadLine();
if(restart.ToUpper() == "R") {
//Call the Main method or restart the app
}
Console.ReadKey();
}
Note: the main method contains some user written data.
How can I do this?
Ok you have a main
void main(...)
{
some code
}
All you need to do is...
void main()
{
runStartUpCode();
}
void runStartUpCode()
{
some code
}
Then when you need to restart the code, call runStartUpCode() again.
if(restart.ToUpper() == "R") {
Close();
System.Diagnostics.Process.Start(Application.ExecutablePath);
}
static void Main(string[] args) {
try {
// code here
} catch /* or finally */ {
DisplayMessage(/* pass in any state from Main() here */);
}
}
static void DisplayMessage(/* passed in state from Main() */) {
// original DisplayMessage() code
// if R was pressed
Main(/* put any args to pass to Main() in here */);
}
I actually just got done with this problem earlier by the time you read this post. I kind of duplicated the ORIGINAL main method, changed a few options on the original, and left the copy to call the new main method. Here is what I mean.
static void Main(string[] args)
{
Program CallingTheRealMain = new Program();
CallingTheRealMain.Main2();
}
public void Main2()
{
//Any code here
}
I originally needed to do this because I needed to loop back to the main method but couldn't because it was static. This code worked fine for me, hope it does for you too if you choose to implement it. Hope I helped. Happy coding!
DialogResult result = MessageBox.Show("Do You Really Want To Logout/Exit?", "Confirmation!", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
this.Close();
System.Diagnostics.Process.Start(Application.ExecutablePath);
}
I think your design approach should change if what your app to autorestart.... here's a Pseudocode
main (){
errorObj = null;
internalFunct(errorObj);
if(errorObj != null) return;
secondINternalFunction();
}
Running the app...
while(!errorObj){
main();
}
Why i prefer this approach, because Main, or function recall is avoided... If your working with small memory, there is not point recalling main on the stack of limited space... you have no choice but to be iterative...
New to C#, I apologize for mistakes.
Use this:
static void Restart() {
String[] n = new String[10];
n[0] = "hi";
Main(n);
}
Main takes a string array for reasons I am unaware of. Seems useless to me, because I tried removing it and nothing seemed to change. So, maybe this works too:
Try removing the string[] args part of Main() so you can just type Main(); without
issues.