C 语言模拟密码输入(显示星号)

文章介绍了一种在C语言中模拟密码输入的方法,通过使用getch()函数避免密码在控制台上直接显示,而是用星号回显。当用户按下删除键时,程序会删除前面的星号并在字符数组中相应位置跳过。在输入达到预设最大长度或用户按回车键时,输入结束。
一个安全的程序在用户输入密码时不应该显示密码本身,而应该回显星号或者点号,例如······******,这在网
页、PC 软件、ATM 机、POS 机上经常看到。但是 C 语言没有提供类似的功能,控制台上只能原样显示用户输
入的字符。
我们完全可以模拟密码输入的效果,请先看下面的代码:
1. #include <stdio.h>
2. #include <conio.h>
3. #include <ctype.h>
4. #define PWDLEN 20
5.
6. void getpwd(char *pwd, int pwdlen);
7.
8. int main(){
9. char pwd[PWDLEN+1];
10. printf("Input password: ");
11. getpwd(pwd, PWDLEN);
12. printf("The password is: %s\n", pwd);
13. return 0;
14. }
15.
16. /**
17. * 获取用户输入的密码
18. * @param pwd char* 保存密码的内存的首地址
19. * @param pwdlen int 密码的最大长度
20. **/
21. void getpwd(char *pwd, int pwdlen){
22. char ch = 0;
23. int i = 0;
24. while(i<pwdlen){
25. ch = getch();
26.
27. if(ch == '\r'){ //回车结束输入
28. printf("\n");
29. break;
30. }
31. 
32. if(ch=='\b' && i>0){ //按下删除键
33. i--;
34. printf("\b \b");
35. }else if(isprint(ch)){ //输入可打印字符
36. pwd[i] = ch;
37. printf("*");
38. i++;
39. }
40. }
41. pwd[i] = 0;
42. }
运行结果:
Input password: *********
The password is: 123456789
代码中定义了一个函数 getpwd(),它有两个参数:pwd 为保存密码的内存的首地址,pwdlen 为密码的最大长
度。
函数通过 while 循环来不断读取用户输入的字符,并逐一对它们进行处理:
        如果用户按下回车键,表示输入结束了,getch() 将会读取到\r
        如果用户按下删除键,表示删除前面的字符,getch() 将会读取到\b
        如果用户输入可打印字符,那么就读取该字符并回显星号。
while 循环中之所以使用 getch() 来获取字符,是因为该函数既没有回显也没有缓存,可以立即读取到用户输入
的字符,并且不会在屏幕上显示出来。
从循环条件 i<pwdlen 可以看出,当用户输入的密码超过最大长度时跳出循环,结束输入。
用户按下回车键时,getchar() 将读取到\n 字符,而 getch() 将读取到\r 字符。也就是说,对于不同的字符输
入函数,回车键产生的字符不同,这个细节读者要引起注意。
删除密码的思路
密码保存在字符数组中,当用户按下删除键时,不仅要删除前面的星号,还应该删除字符数组中前面的元素。
需要注意的是,数组中的元素在内存中是连续分布的,无法直接删除。上面代码中,我们并没有对数组元素进
行任何操作,而是将变量 i 减 1,跳过要删除的字符。这些本该被删除的字符依然留在数组中,它们会被后续输
入的字符覆盖掉。第 29 行代码中,我们通过 printf("\b \b");来删除前面的星号。\b 表示退格,也就是光标向后移动一个位置。
退格,输出空格,再退格就能删除前面的星号。例如我们输入了密码 123,它在屏幕上显示为:
***_
输出一个退格,光标向前移动一个字符的位置,变为:
***
此时再输出一个空格,星号就会被覆盖掉,变为:
** _
虽然星号被空格替换掉了,但是光标也同时向后移动了一个位置,这样光标和星号之间就有了一个字符的间隔,
所以还需要再输出一个退格,消除间隔。再输出一个退格后变为:
**_
函数体最后一行代码也至关重要,它向字符数组中添加了字符串结束符,决定者密码在何处结束。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值