I am aware that it is not possible to echo the * while you type in standard ANSI C. But is there a way to display nothing while someone is typing their password in the console. What I mean is like the sudo prompts in a Unix/Linux terminal. Like if you type in the command: sudo cp /etc/somefile ~/somedir
. You are usually prompted for the root password. And while you type it in, the terminal displays nothing. Is this effect possible in C? If it is, how?
The function that you are looking for is: getpass(). You will note, though, that it is marked as "LEGACY". Although it isn't going to go anywhere, the function doesn't allow the size of the input buffer to be specified, which makes it not a very good interface. As Jefromi has noted, the glibc manual provides portable example code for implementing getpass from scratch in a way that allows an arbitrary input size (and isn't LEGACY).
getnpass()
so not every programmer need to reinvent the wheel... –
Anacreontic sudo is written in C, so yes :). The getpass()
function Safyan mentioned is probably what you want, but here's where the actual sudo tool does it if you're interested:
http://sudo.ws/repos/sudo/file/dc3bf870f91b/src/tgetpass.c#l70
The poor-man's method of doing this is to read user input character by character, and after each character is received print out a backspace character followed by *
. The output is technically sent to the console, but it is immediately erased and overwritten by an asterisk (often before that frame is even drawn to the screen). Note that this is not really a secure method and has several security holes, but for low-tech low-security applications, it works.
*This is not ANSI C (Thanks Billy) sample
You can detect keypress with _kbhit(), then get the value using _getch(). Both function will not echo the content on screen.
#include <conio.h> //For keyboard events
#include <stdio.h> //Include this or iostream
#include <locale>
int main()
{
bool bContinue = true;
char szBuffer[255] = {0};
unsigned int nbufIndex = 0;
while (bContinue)
{
if (_kbhit())
{
szBuffer[nbufIndex] = _getch();
if (szBuffer[nbufIndex] == 0xD)
{
bContinue = false;
}
else
{
++nbufIndex;
printf("*");
}
}
}
printf("\n%s\n", szBuffer);
return 0;
}
conio.h
is likely to be available if you're compiling on UNIX or Linux. –
Taut #include <stdio.h>
#include <conio.h>
void main()
{
char pwd[15];
int i;
printf("Enter Password : ");
for(i=0;i<15;i++)
{
pwd[i]=getch();
if(pwd[i]!='\r')
{
printf("*");
}
if(pwd[i]==13)
break;
}
printf("\n \nPassword is : ");
for(i=0;i<15;i++)
{
printf("%d ",pwd[i]);
}
}
conio.h
does not exist in the Linux environment, see #8792817. Further can you explain a little more about your solution? –
Addax I recently wrote this! To read each character individually and to stop printing them you need to disable echoing and canonical mode (which stops input from being read until the return key is pressed).
To achieve this you need to change the terminal attributes:
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
void rawChange(int opt) {
struct termios new;
if (tcgetattr (STDIN_FILENO, &new) != 0)
exit(1); // if something goes wrong exit program
if (opt == 1)
new.c_lflag &= ~(ECHO | ICANON); // to enable
else
new.c_lflag |= (ECHO | ICANON); // to reset
if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &new) != 0)
exit(1); // if something goes wrong exit program
}
Now you just get the password character by character, printing '*' each time a character is read:
#define RETURN_KEY 10
#define DELETE_KEY 127
#define CURSOR_LEFT "\x1b[D" // cursor moves one unit to the left
#define MAX_PASSWORD_LENGTH 64
char * getPassword(void) {
static char password[MAX_PASSWORD_LENGTH + 1];
char c; int i = 0, finish = 0;
rawChange(0); // disable echo and canonical mode
printf("enter password: ");
while (!finish) {
finish = (c = getchar()) == RETURN_KEY;
if (c == DELETE_KEY) { // allows to use delete key
if (i > 0) {
i--;
printf("%s %s", CURSOR_LEFT, CURSOR_LEFT);
}
continue;
}
if (!finish && i == MAX_PASSWORD_LENGTH)
continue;
password[i++] = finish ? '\0' : c;
printf(finish ? "" : "*");
}
rawChange(1); // reenable echo and canonical mode
return password;
}
I learned to do this in this course which teaches how to make a text editor from scratch. If you want a better explanation of everything definitely check it out!
(Edit: just noticed how old this post is but oh well)
© 2022 - 2025 — McMap. All rights reserved.