Masking the user input as asterisks in Windows? - c++

I need to create a simple password program where the program asks user to input password and when user inputs, it shows the characters as asterisks.
Every tutorial out there uses getch() (in conio.h). But I don't want to use it. Is there any easy alternative for doing so?
I'm using Windows 10.
P.S: Please don't confuse this to be a duplicate of this question: Alternative function in iostream.h for getch() of conio.h?
Because that question asks for holding screen output whereas I need to mask the input as asterisks.

We are here in non standard functionality. So, whatever you'll do, it will not be portable.
The native console way would be to ReadConsoleInput() as explained here. In your case, you would first disable the echo and the line input mode by clearing the console mode flags ENABLE_LINE_INPUT and ENABLE_ECHO_INPUT. Then you would react on key events by displaying '*'. Don't forget to restore the inital console mode at the end.
A shortcut would be to just save and change the console mode (as shown in the code above), an then looping for cin.get() and echoing cout<<'*'; followed by cout.flush(); to be sure that the output doesn't wait in a buffer, creating discomfort for the user.

Related

How do i prevent "cin" from changing lines in the output screen after each input

how should i write or change the input code in c++ so that in the ouput screen there is no change of line. That is, even after encountering a "cin" statement and taking the respective input from the user and also after pressing enter the cursor remains in the same line . is there any way to do so? please help.
The language and its standard library have no notion of screen or cursor.
What you want to do definitely depends on your architecture and operating system. On POSIX systems, disabling echo on the terminal may be a starting point.

Echo characters in istream to an unusual "device"

I want to make a version of cin that works in a graphics display window (it's SDL, but I don't think that matters here): that is, when you type, the characters echo into that window rather than the console window. The solution should be cross-platform.
I have this page to tell me how to get characters NOT to echo to the console window: Reading a password from std::cin
...but what I don't know how to do is to make the characters echo on the new graphics display window.
One thing I could do is intercept keyboard events, and if one happens, print the character. But this wouldn't perfectly echo the actual behavior of the istream buffer, because of repeating keys, backspace, enter, tab, and also the real behavior of cin in that if you are typing before C++ gets to the cin, it will put that stuff you typed on the screen at that point.
I think this echoing is done inside the call to _read (read in the Unix world), and that I'm not sure how to access.
TIA.
The behaviors you're talking about are not done by cin nor read() syscall; buffering and processing of special character is done by the terminal emulator and the shell.
You do need to intercept key events and implement these yourself. Alternatively, some terminal emulators (e.g. VTE widget in Gnome) were designed so they can be embedded into another program. You might want to look at that option.
Considering your application is running in a window you shouldn't read input from the console . It's probably possible but you'll have to switch to the terminal window from where you started the window each time you want to input text. If you take this route you need to disable tty echo: http://man7.org/tlpi/code/online/dist/tty/no_echo.c.html (for Linux). Check out http://www.cplusplus.com/forum/general/12256/ for some solutions for Windows too. I don't think there is a solution that works for both so you'll need to bury some #ifdef's in some utility functions.
Since you're using SDL you should probably use SDL's input functions.
Check out http://www.libsdl.org/docs/html/guideinputkeyboard.html
And, more specific to your needs: http://wiki.libsdl.org/moin.fcg/Tutorials/TextInput

Detect keypress in console application?

I need to detect a keypress in a console application, without prompting the user. Basically, my app is normally a daemon that listens to a special input device, but i need to simulate it on a dev box using the keyboard in interactive mode. How can I do this? - Im on a Linux system.
If you can't block while waiting for input, then you can use e.g. select to check if the STDIN_FILENO file descriptor is ready for reading, and if it is then you can use normal input functions (scanf, fgets std::getline, etc.).
You check this answer which explains how to read from the input events ( usually /dev/input/event0)
Or directly check the answer's source :
Credits do not go to me, this code is taken from the Ventriloctrl hack to get keystrokes.
http://public.callutheran.edu/~abarker/ventriloctrl-0.4.tar.gz
This text explaines hw to do such a thing. http://thc.org/papers/writing-linux-kernel-keylogger.txt

Async Console Output

I have a problem with my application win32 console.
The console is used to give commands to my application. However, at the same time it is used to output log messages which mostly comes from asynchronous threads. This becomes a problem when the user tries to write some input and simultaneously an async log message is printed, thus thrashing the display of the users input.
I would like to have some advice in regards to how to handle such a situtation?
Is it possible for example to dedicate the last line in the console to input, similarly to how it looks in the in-game consoles for some games?
You can use SetConsoleMode to disable input echo and line editing mode. You can then echo back input whenever your program is ready to do so. Note that this means you will need to implement things like backspace manually. And don't forget to reset the mode back when you're done with the console!
This is possible using the Console API, but it involves quite a bit of work and all the threads that use the console will have to cooperate by calling your output method rather than directly calling the Console API functions or the runtime library output functions.
The basic idea is to have your common output function write to the console screen buffer, and scroll the buffer in code rather than letting the text flow onto the last line and scroll automatically. As I recall, you'll have to parse the output for newlines and other control characters, and handle them correctly.
You might be able to get away with using "cooked" console input on the last line, although in doing so you risk problems if the user enters more text than will fit on a single line. Also, the user hitting Enter at the end of the line might cause it to scroll up. Probably best in this situation to use raw console input.
You'll want to become very familiar with Windows consoles.
Any time you have asyncronous threads trying to update the same device at once, you are going to have issues like this unless something synchronizes them.
If you have access to everyone's source code, the thing to do would probably be to create some kind of sync object that every task must use to access the console (semaphore, etc).

Make a 'press any key' routine that is compatible with redirected standard input

I've got a C/C++ program that runs in a console window, and prompts the user to press any key to continue, or 'q' to quit. It currently uses _kbhit() to detect if a key has been pressed, and then uses _getch() to determine what character it was.
Now I want to be able to automate this program (from a C# app using a Process with RedirectStandardInput and CreateNoWindow set). Obviously I can no longer rely on _kbhit() as it uses ReadConsoleInput(), which fails when launched using my C# app. In my C# app I use process.StandardInput.Write("A") to push something onto the stream in an attempt to get my console app to continue.
In the console app I have used SetConsoleMode() to clear the ENABLE_LINE_INPUT flag so that I can use getchar() to return as soon as a character is pressed, and this works reasonably well (when I press a character key in the console window as well as when the call is made from the c# app). However, it has flaws in that it now only accepts characters keys (i.e. no F, Alt, Shift keys etc.) which isn't too big a problem, but moreso I seem to have to press return twice (and this is a key that lots of people will likely choose to press in the 'any key' situation).
Does anyone know how I can make the console app respond to a key (any a bonus, charcters and return only is acceptable) pressed ONCE, whilst still responding to a single character pushed onto the stream from my C# app?
Something I did notice, calling system("PAUSE") gives the exact behaviour I want, other than knowing what key was pressed so that I can quit on 'q'. I don't know how PAUSE does it though, and it doesn't let me use my custom message either :(.
I'm sure there's a really obvious solution, but it has been driving me mad. Any thoughts are much appreciated!
There are two issues with the resolutions:
Neither the C or C++ languages have
portable functions for waiting for a
keyboard key to be hit. It's an
operating system (platform) issue.*
C and C++ have different methods for
resolving I/O. Choose your
language, C or C++.
In my C++ console applications, I ask the user to "Press Enter to Continue" and use the ignore method of cin:
void Pause(void)
{
std::cout << "Press ENTER to continue.\n";
std::cout.flush(); // Insurance, make sure the text is displayed.
std::cin.ignore(100000, '\n'); // Ignore characters until an ENTER (newline) is received.
return;
}
I suggest you create a single file with the Pause function. You can write different versions for different platforms and let the build system select the correct file.
Not all platforms that run C or C++ are required to have keyboards. Many embedded systems don't have keyboards. Also, many windowing systems receive messages, events or signals when a key is pressed. Again, something different and not standard.
Here is a very good implementation for C++. Be sure to read over the entire tutorial, as I it may initially appear that it doesn't help you.
http://www.daniweb.com/forums/thread90228.html
Use cin.get(). This returns the appropriate key.
Thank you for all your responses, I've learned a lot about handling input!
However, I couldn't get anything to work exactly how I wanted, so I had to abandon the unified approach and put in a check to see if it was running in a window. If it is, I stick with _kbhit(), and if not I use PeekNamedPipe(), which gives me the number of characters sent from my C# app without transfering them into the stdin buffer. There's still a few issues that I have to work out to do with clearing any data that I don't want from the pipe, but it's solved my initial problem.
Thanks again for all the suggestions, they will undoubtably come in handy next time I have an input nightmare :)