Masking Text with *'s

Hey I'm trying to help make a game, nothing big or important it's just for the fun of it, but what I want to do is have it so when the user inputs what they want, the second player (who plays on the same keyboard right there), cannot read the number that is being input. For example, player one enters a single number 1, 2, or 3. But player two is supposed to pick a choice number as well, but neither should be able to see each other's input. They don't input at the same time, although if someone could figure that out that'd be cool. But the real issue is masking the text, or even just making it so the text doesn't echo back as you type.
Here's what it should look like if you don't get what I'm saying:

Player one enter: *
(Player one hits enter)
Player two enter: *


I have searched Google, even this forum but I haven't found anything that works for me. Although, I have seen a lot about _getch(), but everyone where I found it said it wouldn't work. Is it possible to mask/not echo text in C++?
Last edited on
Well, getch could be a solution but you will have chars, not numbers:
1
2
3
4
5
6
7
8
9
10
char get=0;
while (get!='\r')
{
     get = getch();
     if (isdigit( get ) )
     {	
          cout << '*';
          //use here get as numeric character value ( '0', '1' ... )
     }
}


Something better could be achieved using windows.h, could you?
Last edited on
> Is it possible to mask/not echo text in C++?

No. C++ has no concept of devices. You will have to do something OS-specific.

If you are on Windows, take a look at SetConsoleMode() and ReadConsoleInput().
http://msdn.microsoft.com/en-us/library/ms682073(VS.85).aspx

If you are on *nix, or if you wish your game to be cross-platform, use NCurses:
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/

Reading input at the same time is just a matter of knowing which keys belong to which player.

Hope this helps.
Thanks for the help, but I guess I should have mentioned that the OS in which I am attempting this is FreeBSD. I don't really care how it is done, char or int, even string will work fine. All I care is that the text is not echoed the same as it is typed, if anyway possible - as long as it will run in a .cpp program.
++ to using NCurses
sudo apt-get install ncurses-devel

(or somesuch)

Either that or download, compile, and install it according to the instructions in the HOWTO link I gave you.

The curses library really is the easiest way to do it on the console. The other good option would be to use Xlib/KDE/Gnome/Tcl-Tk/Qt/whatever and make a GUI app to get X keyboard events directly. Or SDL.
So what I am getting out of this is that there is no real way to mask text in C++?
As Duoas explained above, what you are asking to do is operating system dependent. Having said that, C++ allows you to write software that does just about anything, so strictly speaking, yes, you can, using C++, do what you want. Duoas' point is that there is no way to do it in a platform independent fashion.

Since you are using FreeBSD, you can probably do this by fiddling with the termios settings for stdin. See the ECHO flag.
Could you explain a bit more? An example or something of how to do whatever?
Here's a program that turns off line buffering of stdin and also turns off echo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

int main()
{
    struct termios oldSettings, newSettings;

    tcgetattr( fileno( stdin ), &oldSettings );
    newSettings = oldSettings;
    newSettings.c_lflag &= (~ICANON & ~ECHO);
    tcsetattr( fileno( stdin ), TCSANOW, &newSettings );    

    while ( 1 )
    {
        fd_set set;
        struct timeval tv;

        tv.tv_sec = 10;
        tv.tv_usec = 0;

        FD_ZERO( &set );
        FD_SET( fileno( stdin ), &set );

        int res = select( fileno( stdin )+1, &set, NULL, NULL, &tv );

        if( res > 0 )
        {
            char c;
            printf( "Input available\n" );
            read( fileno( stdin ), &c, 1 );
        }
        else if( res < 0 )
        {
            perror( "select error" );
            break;
        }
        else
        {
            printf( "Select timeout\n" );
        }
    }

    tcsetattr( fileno( stdin ), TCSANOW, &oldSettings );
    return 0;
}

So how could I use that for what I want to do? Which is simply for a user to type in a single number 1-3, I guess the variable being type char, and have the computer compare it to a separate input, and tell you the result.
~ICANON turns off canonical mode, which is to say, it makes stdin character buffered so that keypresses are available to the application as soon as they occur as opposed to waiting until the user presses ENTER. This may or may not be what you want; if not, don't include the flag.

~ECHO turns off echo mode, which is what you are asking for.
So do lines 11-16 using ~ECHO only on line 15, read the input using cin or whatever, then do lines 11-16 again this time |= ECHO to turn echo back on.

i tried it, it worked for the program, but after the program had executed, the terminal still had echo off, so everytime i execute the prog i need to exit terminal and open it up again. Is there an easy fix for this?
You can tell when some people really don't bother trying something them self at all
You need to turn echo on before exiting your program.
Belkdaddy, the others here are upset at you because jsmith gave you a complete example that explicitly fixes the terminal to the same state it was before it was executed.

For your future reference, when given an example, do the following:
1. Copy and compile the example exactly as given to you. Run it and see how it works.
2. Take a look through the code and see what every part does.
Jsmith failed to give you any commentary, so you may also want to spend some time with Google.
For Unix stuff, good search terms often start with "man": "man tcsetattr", "man select", etc.
3. Spend some time playing with the code to see exactly how each piece affects the program.
4. If you still can't make your code go with what you learned, post back with:
a. A copy of your code that is still giving you trouble
b. Ask for help to figure out what you misunderstood/did wrong.

Alas, playing with the console is a tricky thing, and if you want to do it directly, it requires a good deal of care to get it right.

On line 13, jsmith captured the console's current settings. On line 48 he restored them.

I'm not angry with you, but I am saying -- if your major requires you to take some basic computer programming courses -- it is because you are required to think about things in an exacting way. That is the hardest thing to learn, but the most rewarding. Don't cheat yourself out of it.

Hope this helps.

[edit] I am aware that the OP was epiqu1n. He has acquitted himself well. Sorry for any confusion..
Last edited on
Topic archived. No new replies allowed.