9

I am writing a program in C++ where I am supposed to receive a string from user without displaying it on screen (for example: apassword). I tried using cin and gets to accept the string. But both will echo the characters entered by user in console.

So is there any function or any other way of doing it in C++?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
ZoomIn
  • 1,237
  • 1
  • 17
  • 35
  • 1
    and Hi at beginning of post is removed automatically! – ZoomIn Feb 15 '12 at 11:12
  • 1
    Yes, and that’s a good thing: we try to keep questions (and answers) to the point here. Not using “Hi” and “thanks” is *not* considered impolite on Stack Overflow. Anyway, have an upvote, good question. – Konrad Rudolph Feb 15 '12 at 11:14
  • 1
    check out *NCurses* (unix) and *PDCurses* (windows). – Alok Save Feb 15 '12 at 11:16

3 Answers3

5

How to avoid that data being read via cin shows up on the console depends very much on the console; it's certainly operating system dependant.

On Windows, you can use the SetConsoleMode function to enable/disable the echo for any file handle, including the standard input handle.

Something like

void enableStdinEcho( bool b ) {
    HANDLE hStdin = ::GetStdHandle( STD_INPUT_HANDLE ); 
    DWORD mode = 0;
    ::GetConsoleMode( hStdin, &mode );
    if ( b ) {
        mode |= ENABLE_ECHO_INPUT;
    } else {
        mode &= ~ENABLE_ECHO_INPUT;
    }
    ::SetConsoleMode( hStdin, mode );
}

could probably be used to toggle the echo on stdin.

Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
  • On windows system it worked like charm!now trying getpass with gcc-linux. – ZoomIn Feb 15 '12 at 11:40
  • 1
    void enableStdinEcho( bool b ) { int ttyDevice = STDOUT_FILENO; struct termios termAttributes; /* Make sure file descriptor is for a TTY device. */ if ( ! isatty(ttyDevice) ){ exit(1); }else { if (tcgetattr(ttyDevice, &termAttributes) != 0){ exit(1); }else { if(b == false) termAttributes.c_lflag &= ~ECHO; else termAttributes.c_lflag |= ECHO; tcsetattr(ttyDevice, TCSANOW,&termAttributes); } } } equivalent in unix/linux based.Got this stuff working. – ZoomIn Feb 15 '12 at 13:32
3

The C++ standard does not define a mechanism to do this. You have to rely on a platform specific library. For example with gcc/glibc use getpass

http://www.gnu.org/software/libc/manual/html_mono/libc.html#getpass

There might be other libraries that abstract these functions and provide a platform independent wrapper.

iain
  • 10,798
  • 3
  • 37
  • 41
  • No need for a full fledged library, `tcsetattr` usually suffices on unices. The manpage for glibc `getpass` even says: "This function is obsolete. Do not use it." – PlasmaHH Feb 15 '12 at 12:31
  • Yes tcsetattr would sufficiently do for gcc. – ZoomIn Feb 15 '12 at 13:34
2

This is not a C++, iostream etc. question at all - it's specific to the terminal you're using.

See this question for ideas, and then ask a question specific to your terminal if it isn't covered there and you can't use ncurses.

Community
  • 1
  • 1
Useless
  • 64,155
  • 6
  • 88
  • 132