C命令行密码输入

我想允许用户使用命令行界面输入密码。 但我不想在屏幕上显示此密码(或显示“****”)。

怎么用C做? 谢谢。

更新:

我只在Linux上工作。 所以我实际上并不关心Win或其他系统。 我试过卢卡斯的解决方案,它工作得很好。 但是,我还有另一个问题:

  1. 如果这是单个进程和单线程应用程序,更改termios的设置会影响不同的终端吗?

  2. 1个进程怎么样 – multithreading,多进程 – multithreading?

非常感谢。

如果您的系统提供它, getpass是一个选项:

#include  /* ... */ char *password = getpass("Password: "); 

键入字符时不会显示任何内容。

如果您使用的是UNIX环境,则可以关闭命令行的ECHO。

 #include  #include  #include  #define SIZE 100 void getPassword(char password[]) { static struct termios oldt, newt; int i = 0; int c; /*saving the old settings of STDIN_FILENO and copy settings for resetting*/ tcgetattr( STDIN_FILENO, &oldt); newt = oldt; /*setting the approriate bit in the termios struct*/ newt.c_lflag &= ~(ECHO); /*setting the new bits*/ tcsetattr( STDIN_FILENO, TCSANOW, &newt); /*reading the password from the console*/ while ((c = getchar())!= '\n' && c != EOF && i < SIZE){ password[i++] = c; } password[i] = '\0'; /*resetting our old STDIN_FILENO*/ tcsetattr( STDIN_FILENO, TCSANOW, &oldt); } int main(void) { char password[SIZE]; printf("please enter password\n"); getPassword(password); printf("Do something with the password <<%s>>\n", password); return 0; } 

函数getpass现在已经过时了 。 使用termios 。

 #include  #include  void get_password(char *password) { static struct termios old_terminal; static struct termios new_terminal; //get settings of the actual terminal tcgetattr(STDIN_FILENO, &old_terminal); // do not echo the characters new_terminal = old_terminal; new_terminal.c_lflag &= ~(ECHO); // set this as the new terminal options tcsetattr(STDIN_FILENO, TCSANOW, &new_terminal); // get the password // the user can add chars and delete if he puts it wrong // the input process is done when he hits the enter // the \n is stored, we replace it with \0 if (fgets(password, BUFSIZ, stdin) == NULL) password[0] = '\0'; else password[strlen(password)-1] = '\0'; // go back to the old settings tcsetattr(STDIN_FILENO, TCSANOW, &old_terminal); } int main(void) { char password[BUFSIZ]; puts("Insert password:"); get_password(password); puts(password); } 

要以便携方式执行此操作,您需要使用标准化或事实上的标准库。

参见man 3 termiosman 3 ncurses

这是一个适用于Linux和其他Unix系统的程序……

 #include  int main(void) { int f = open("/dev/tty", 0); char s[100]; system("stty -echo > /dev/tty"); f >= 0 && read(f, s, sizeof s) > 0 && printf("password was %s", s); system("stty echo > /dev/tty"); return 0; } 

可以进行许多改进。 使用termios可能会更好,它可以避免fork()和system()可能出现的安全问题。 使用标准I / O来读取密码可能会更好。 (正如所写的那样,必须删除键入的换行符。)Linux中有一个getpass()函数,但是其他一些函数被标记为“过时了。不要使用它。”。 处理SIGTSTP可能是个好主意。

总的来说,我可能会寻找一个处理所有这些小问题的现有解决方案……

对于C / commandline / linux,请参阅:

 man getch man noecho 

看看关于noecho getch noecho 。 我自己从未尝试过这个。

在bash中,如果你使用read -s它不会在屏幕上回显:

 > read -sx  > echo $x  

如果您可以访问curses库,则可以使用noecho 。 如果您使用的是Microsoft的C编译器,则可以使用_getch 。 但是afaik,这两个都把你绑在控制台上。 如果您需要读取stdin,无论它是来自控制台还是文件或管道命令,您需要告诉操作系统它应该如何处理控制台 。

  #include #include using namespace std; int main(){ char *pass = new char[20]; cout<<"Password :"; int i=0; while( ( pass[i]=getch() ) != '\n' && pass[i] != '\r' && i<19 ) {putchar('*'); i++;} pass[i]='\0'; cout<