Thread: Input a password and replace with *s

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    230

    Input a password and replace with *s

    Hi. I was wondering if there was a way to replace characters input by fgets() with * since a password is being input. I can't think of any way to do it while inputting the password. I don't think fgets() can do it but again I can't think of any other function that can.
    getchar() would not work for me, since I don't know how many characters will be input (even though there is a maximum ofcourse).

    I know I can print '\r' after I input it and output something like "Password succesfully input" but I hoped there would be a way to do it while inputting the password.

    Thank you.

  2. #2
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    I guess you could use getchar() in a while loop. Something like:
    Code:
    while((string[i]=getchar()) != '\n')
    {
        i++;
        putchar('*');
    }
    I havent tried it so i'm not sure how well, or if, it will work.

  3. #3
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Except that you have to push enter after entering a character

    Use a library like curses or pd curses (for Windows/Unix)

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    This is non-trivial to do in standard C, since the way you "turn off echo" [echo here means "show what's being typed"] is system dependant.

    There are two choices:
    - a cross-system library (such as ncurses)
    This is good because you don't have to dig into the system specific details. Drawback is that if you are doing a really simple application, it may be a bit of "sledghammer to crack nut" approach.

    - Implement one or more system specific functions to do this.
    This means understanding (or finding someone else who understands) the system architecture and fidning the right way to turn off the echo to console.

    If you actualy want stars to appear as you type, you'll also have to "disable cooking" - cooking is where the user enters a whole line of text at once, and the application doesn't see the backspace/delete presses that the user may have done to correct the input. This is another, closely related function to the "disable echo" [actually, it's usually just another flag to say "Disable cooking" along with the "Disable Echo" flag].

    You can't use fgets() if you want stars to appear as they are typed tho', as fgets still waits for the whole line to be complete. You'll have to use getchar() or some such.

    I have written code for this on Unix/Linux, OS/2 and Windows at different times.

    If you tell us what system you need this for, then I'm sure someone here can tell you how to do it.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    If you're using VC++, it's extremely easy - just use getch() and print out a '*'.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Except that you have to push enter after entering a character
    Oh yeah I forgot about that :/
    I tried the function using DevC++ but It dosent seem as if it will work because of the getch(). And it dosent seem as if getch() is featured in DevC++ either, or at least so it says here .

    The only way I know how to do keyboard event polling in C/C++ is using SDL, but that would be entirely inappropriate for this. So yeah maybe something like ncurses would be best here.

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You can use getche() in Dev-C++. You just have to erase the characters that are echoed. I suggest
    Code:
    printf("\b*");
    In Dev-C++, getch() is defined as (at least on my version)
    Code:
    #define getch() getchar()
    so it doesn't do what you're looking for.

    ncurses might still be a good idea, though, especially if you're doing other screen manipulation.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Oh ok, but wouldent it be the same as getchar then?

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Oh ok, but wouldent it be the same as getchar then?
    Yep, and that's why getch is implementation-dependent.
    My best code is written with the delete key.

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    230
    I am programming for Windows. Even though I would like it to be portable, I still don't mind to have it system specific.

    Thanks for the replys

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    #include <windows.h>
    ...
    DWORD origKBMode = 0;
    ...
    void SetKbdModeRaw(void)
    {
    	DWORD mode;
    	GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode);
    	if (origKBMode == 0)
    		origKBMode = mode;
    	mode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
    	SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode);
    }
    
    void RestoreKbdMode(void) 
    {
    	SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), origKBMode);
    }
    In your code, call SetKbdModeRaw() and when you have got the password, call RestoreKbdMode().

    However, it seems that the standard C functions don't quite work right with this - so you may still be better off using getch(). I think the problem has to do with line endings.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Something I made awhile ago:

    Code:
    char *getPass(char *szBuffer, size_t len)
    {
    	size_t i;
    	HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
    	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    	DWORD dwOld, dwNumRead, dwNumWritten;
    	if((hIn != INVALID_HANDLE_VALUE) && (hOut != INVALID_HANDLE_VALUE))
    	{
    		if(GetConsoleMode(hIn,&dwOld))
    		{
    			if(SetConsoleMode(hIn,ENABLE_PROCESSED_INPUT))
    			{
    				for(i=0;i<len-1;i++)
    				{
    					if(ReadConsole(hIn,&szBuffer[i],1,&dwNumRead,NULL))
    					{
    						if(szBuffer[i] == '\r')
    						{
    							break;
    						}
    						else WriteConsole(hOut,"*",1,&dwNumWritten,NULL);
    					}
    					else break;
    				}
    				WriteConsole(hOut,"\n",1,&dwNumWritten,NULL);
    				szBuffer[i] = '\0';
    				SetConsoleMode(hIn,dwOld);
    				return szBuffer;
    			}
    		}
    	}
    	return NULL;
    }
    Use it like fgets(). As was mentioned, the C buffers might not be perfectly setup with the buffers used here (since the C setup wraps the Windows API buffers). Beware.

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    230
    OK thanks I'll try to try them today. But I don't really understand what you mean by
    the C buffers might not be perfectly setup with the buffers used here (since the C setup wraps the Windows API buffers).
    Do you mean that other functions might not work well with the password array after using these functions? or will all buffers mess up?

  15. #15
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by dwks View Post
    You can use getche() in Dev-C++. You just have to erase the characters that are echoed. I suggest
    Code:
    printf("\b*");
    In Dev-C++, getch() is defined as (at least on my version)
    Code:
    #define getch() getchar()
    so it doesn't do what you're looking for.

    ncurses might still be a good idea, though, especially if you're doing other screen manipulation.
    getch() is a macro for getchar() in the Dev-C++ 4.0 version, but it works as expected in 5.0 (or 4.9 as it may be, cause it's still technically beta).
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Password replace with * on entry
    By gasie@medemass. in forum C++ Programming
    Replies: 4
    Last Post: 11-13-2008, 02:33 PM
  2. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM
  3. Replies: 1
    Last Post: 04-24-2005, 03:45 AM