I am not using windows forms so this is not a duplicate of Capture keystroke without focus in console. Please remove the duplicate label or direct me somewhere else
So have been away from C# for a long time and trying to get back into it. I am messing with a small console app that requires inputting text from the user. The whole program works fine but now I want to add a check to see if escape is ever pressed.
I originally used ReadKey, but that just checks the current key which has two problems.
1. it uses the key pressed, so strings are missing a character (the one which was checked)
2. it is only in the moment. I want it to be passively waiting until its pressed
What would be the best way to do this?
ex:
I type the string "Hello World!"
If I press the desired key(lets say escape) at any time, I want it to react. Otherwise the string should be entered like normal
edit
example of made up dictionary program (yes, I know there is already a class for this)
while (Console.ReadKey().Key != ConsoleKey.Escape)
{
string entry = Console.ReadLine();
if (!entry.Contains(","))
{
...
}
else
{
...
}
}
Thank you all very much for your time.
Not sure what you're getting at but you can use this to detect if the Escape key was pressed.
if (Console.KeyAvailable)
if (Console.ReadKey(true).Key == ConsoleKey.Escape)
{
// Do something
}
}
Or alternatively use a loop that breaks when Escape is entered:
var x = Console.ReadKey();
while (x.Key.ToString() != "Escape")
x = Console.ReadKey();
Related
I am currently working on a little lottery console game and wanted to add a "Working" mechanic. I created a new method and want to add multiple tasks where you have to press a specific key like the space bar for example multiple times. So something like this (but actually working):
static void Work()
{
Console.WriteLine("Task 1 - Send analysis to boss");
Console.WriteLine("Press the spacebar 3 times");
Console.ReadKey(spacebar);
Console.ReadKey(spacebar);
Console.ReadKey(spacebar);
Console.WriteLine("Task finished - Good job!");
Console.ReadKey();
}
The Console.ReadKey() method returns a ConsoleKeyInfo structure which gives you all the information you need on which key and modifiers were pressed. You can use this data to filter the input:
void WaitForKey(ConsoleKey key, ConsoleModifiers modifiers = default)
{
while (true)
{
// Get a keypress, do not echo to console
var keyInfo = Console.ReadKey(true);
if (keyInfo.Key == key && keyInfo.Modifiers == modifiers)
return;
}
}
In your use case you'd call that like this:
WaitForKey(ConsoleKey.SpaceBar);
Or you could add a WaitForSpace method that specifically checks for ConsoleKey.SpaceBar with no modifiers.
For more complex keyboard interactions like menus and general input processing you'll want something a bit more capable, but the basic concept is the same: use Console.ReadKey(true) to get input (without displaying the pressed key), check the resultant ConsoleKeyInfo record to determine what was pressed, etc. But for the simple case of waiting for a specific key to be pressed that will do the trick.
I would like to check if the user will make a kepress again after the first one to implement a pause function in a while cycle. The console window is not on focus so I can't use Console.Read()
while (true)
{
if (GetAsyncKeyState(0x21) != 0)
break; //work just fine, if ESC press it exit while
if (GetAsyncKeyState(0x05) != 0)
{
sw.Start();
while (sw.ElapsedMilliseconds < 2000)
{
// if side mouse button is press, it wait 2sec, work just fine
}
sw.Reset();
}
if (GetAsyncKeyState(0x42) != 0)
{
while (GetAsyncKeyState(0x42) == 0)
{
// wait the second B pressing to resume but it dosen't work
}
}
main_function();
}
This code seems to not work, I check GetAsyncKeyState with writeline and it seems that it get the keypressed state for few ms so the pause cicle will end.
I seems that in console c# I can't use ad hoc functions that c# have for forms to check it.
Thanks!
The solution is:
// if pressed the first time
if (GetAsyncKeyState('B'))
{
//if previously detected and still held down
while (!((GetAsyncKeyState('B')) & 0b1000'0000'0001))
{
//wait in here
}
//if key not pressed
while (!GetAsyncKeyState('B'))
{
//wait in here
}
//if you get here, B was pressed, released and pressed again
}
I don't recommend using GetASyncKeyState for anything but quick and simple Proof of Concepts due to the remarks you will read below.
From MSDN:
Return value
Type: SHORT
If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.
Important remarks:
Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to the pre-emptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon.
I am building a calendar. Here I want to add members to my meeting. After every name I want to press enter to add it. When I press, for example X I want to leave the "add member" process and go to next step, for example, "adding a meeting title".
How can I add members to my array? How can I go to the next step when I'm done entering names? This code doesn't work:
Console.Write("Enter members here: ");
memberList = Console.ReadLine();
string[] memberList;
You'll need to use a conditional loop to accomplish this, a while loop would work pretty good.
Also, using a List<string> would be better in this scenario since you (i) need to add things to it, and (ii) you don't know how big to make the array when you first declare it since you don't know how many names the user will enter.
Something like:
var names = new List<string>();
var input = Console.ReadLine();
while (input.ToUpper() != "X")
{
names.Add(input);
input = Console.ReadLine();
}
foreach (var name in names)
{
Console.WriteLine(name);
}
If you're wanting to move to the next step immediately after an user presses X (without them having to press Enter), you can look into using Console.ReadKey but it'd be more complicated since you'd have to collect one character at a time to get the name and check if they key pressed is Enter, in which case you'd move on to the next name. There's also the complexity of known when a "X" is just part of someone's name, e.g. Xavier, or whether meant to move on to the next step.
Assuming the user types in the following: "Jake, Julia, Craig"
string[] memberlist = Console.ReadLine().Split(',');
Eventually you need to .Trim() on every name cause of the whitespace after the comma.
Edit: For a "multiline" solution look at #Jeff Bridgman post.
I have exercise/drill/homework assignment to create a C# program to compute the value of a number raised to the power of a second number. Read the two numbers from the keyboard.
Ask the user for an integer.
Print the integer back to the screen and asked if it is correct.
If the integer is correct, continue on.
If the integer is incorrect, start program from the beginning.
I have two questions:
Can and how do I programmatically clear the console window?
Start over, do I call the Main method or the Class?
How do I do either, calling the main method or the class?
Here's what I've written so far:
using System;
using System.Text;
namespace CalcPowerOfNums
{
class Program
{
//Declaring the two main string variables to be used in our calculation.
string firstUserString;
string secondUserString;
static void Main(string[] args)
{
//Ask the user for the first number.
Console.WriteLine("Enter your first number and press the Enter/Return key");
string firstUserString = Console.ReadLine();
//Make sure this number is correct.
Console.WriteLine("You want to find the power of {0}?\n" , firstUserString);
//Declaring, Initializing string variables for user answer.
string firstAnswer = "";
//Make user confirm or deny their choice.
Console.WriteLine("Press the lowercase letter y for yes");
Console.WriteLine("Press the lowercase letter n for no");
Console.ReadKey();
//If user answer is yes, move on… It user answer is no, start program over.
do
{
if (firstAnswer == "y")
continue;
if (firstAnswer == "n")
}
Looking at the Console class, you will find a Clear method that will clear the console screen. As to calling Main, that will be called automatically by default in a console project as long as you have declared it. You can have a look in your project properties at the Startup Object setting.
When you say "start the program over" I am assuming you mean clear the window and ask for the input again, not reload the entire process.
You can use Console.Clear() to clear the console window. The main method is called automatically from Program.cs. Just place your main code in a while loop and loop until you get the desired input. If you don't get the desired input, just issue a Console.Clear() and ask again until you do.
I have two questions: Can and how do I programmatically clear the console window?
Yes, by calling Console.Clear.
Do I call the Main method or the Class?
You cannot invoke a class, and you should never call main directly. Just put a do/while loop around it with 'is correct' as the condition:
do {
...all regular code...
} while(firstAnswer == 'y');
What about:
Console.Clear();
?
you should make functions for this. Put the enter name part in a function then call this function at the start of the Main function and in the if statements.
I'm porting a small C++ console game to C# and it seems that I can't stop key presses from being printed to the console.
In C++ I get the keystroke with this method, which also suppress the keystrokes from being printed to the console:
bool Game::getInput(char *c)
{
if (_kbhit())
{
*c = _getch();
return true;
}
return false;
}
I tried to do the equivalent in C# by doing:
Key = Console.ReadKey();
But this does not suppress the character from being printed to the console, causing obvious problems. Any ideas on how to remedy this?
You want Console.ReadKey(true)
Obtains the next character or function key pressed by the user. The pressed key is optionally displayed in the console window.
The argument - which is called intercept:
Determines whether to display the pressed key in the console window. true to not display the pressed key; otherwise, false.
The ReadKey method has an overload that takes a bool as a parameter. Pass in true and it will not display the input in the console.