最近频繁需要实现在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
|
#ifndef _WIN32 // 如果不是WIN32环境,则要自定义getch()函数
#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 // _WIN32
/*
* 密码输入函数,参数 passwd 为密码缓冲区,buff_len 为缓冲区长度
*/
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
;
}
/*
// 测试示例(请自行添加头文件)
int main(void)
{
char pass[7];
printf("亲,试试输入密码(长度限制 6):");
passwd_input(pass, 7);
printf("\n%s\n", pass);
return 0;
}
*/
|