最近频繁需要实现在windows控制台下输入星号密码的功能,Unix/Linux那种没有任何屏显的实现总感觉对用户不太友好。今天在自己的Linux代码库中发现了自己去年写图书馆管理系统的时候写的一个密码输入函数。索性拿来修改了接口并且重新优化了处理逻辑后移植到了windows下(其实也就是加上几句条件编译罢了)。代码如下:
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 #ifndef _WIN32 #include <termio.h> int getch (void ) { struct termios tm , tm_old ; int fd = 0 , ch; if (tcgetattr(fd, &tm) < 0 ) { return -1 ; } tm_old = tm; cfmakeraw(&tm); if (tcsetattr(fd, TCSANOW, &tm) < 0 ) { return -1 ; } ch = fgetc(stdin ); if (tcsetattr(fd, TCSANOW, &tm_old) < 0 ) { return -1 ; } return ch; } #else #include <conio.h> #endif char *passwd_input (char *passwd, int buff_len) { char str; int i = 0 ; int enter_num = 13 ; int backspace_num; #ifndef _WIN32 backspace_num = 127 ; #else backspace_num = 8 ; #endif if (passwd == NULL || buff_len <= 0 ) { return passwd; } while (1 ) { if ((str = getch()) != (char )backspace_num) { if (i < buff_len - 1 ) { passwd[i++] = str; printf ("*" ); } } else { if (i != 0 ) { i--; printf ("\b \b" ); } } if (str == (char )enter_num) { passwd[--i] = '\0' ; if (i != buff_len - 1 ) { printf ("\b \b" ); } break ; } else if (str == -1 ) { fprintf (stderr , "Error to set termio noecho.n" ); } } return passwd; }