C语言输入密码时的回显处理

本文介绍了C语言中实现密码输入的两种方式:一种是输入时不显示任何字符,适合于密码输入场景;另一种是在输入时以星号(*)代替实际字符显示,增加用户体验。文章详细解析了getch()和getche()函数的区别及应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言输入密码时的回显处理

之前在写一个C语言的项目的时候,需要一个登陆界面。然而直接输入密码的时候会有回显,于是就百度到了getch(),正好现在在看C语言进阶,再整理一下:

  • getch()
  • getche()
  • sprintf()
  • 输入密码无回显
  • **输入密码回显‘*’ **

函数功能比较

1、getchar()是从键盘的文件缓冲区读取字符,当从键盘输入字符时,可以输入若干个字符(但是它只读取一个),并且最后一定要回车确认。而getch()和getche()是直接从键盘读取(不经过文件缓冲区),输入时只要按下一个键(任意键,也可以是回车键),不需要回车确认,程序就能继续运行了。
2、用getchar()读取字符时,若键盘输入回车,则读取的字符时换行符’\n’(送入缓冲区时被转换,回车总是被转换为换行符再送入缓冲区);而用getch()或getche()读取字符时,若键盘输入回车,则读取的字符是回车符’\r’(不经过缓冲区所以未被转换,不同系统有区别)。
3、getch()和getche()也有不同:前者对输入没有回显,既屏幕上不出现输入的字符,可以用来输入密码;而后者有回显。

getch()

1、头文件:conio.h(不是C标准库中的文件,是Console Input/Output(控制台输入输出)的简写,其中定义了通过控制台进行数据输入和数据输出的函数,主要是一些用户通过按键盘产生的对应操作)
2、函数原型:int getch(void)
3、返回值:读取的字符
4、易错点:

(1)并非标准函数,要注意移植性
(2)所在头文件是conio.h,而不是stdio.h
(3)在使用之前要调用initscr(),结束时要调用endwin()。否则会出现不输入字符这个函数
也会返回的情况。
(4)在不同平台,输入回车,getch()将返回不同数值,而getchar()统一返回10(即\n)
1)windows平台下ENTER键会产生两个转义字符 \r\n,因此getch返回13(\r)。
2)unix、 linux系统中ENTER键只产生 \n ,因此getch返回10(\n)。
3)MAC OS中ENTER键将产生 \r ,因此getch返回13(\r)。

getch()

输入后立即从控制台取字符
1、头文件:conio.h
2、函数原型:int getche(void)
3、返回值:输入字符对应的ASCII码

sprintf()

字符串格式化命令,主要功能是把格式化的数据写入某个字符串中
1、头文件:stdio.h
**2、函数原型:int sprintf( char buffer, const char format, [ argument] … );

buffer:char型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument]…:可选参数,可以是任何类型的数据**

3、返回值:返回写入buffer 的字符数,出错则返回-1. 如果 buffer 或 format 是空指针,且不出错而继续,函数将返回-1,并且 errno 会被设置为 EINVAL。
同时buffer的内容将被改变。

###sprintf_s和snprintf
sprintf_s()是sprintf()的安全版本,通过指定缓冲区长度来避免sprintf()存在的溢出风险
**int sprintf_s(char buffer,size_t sizeOfBuffer,const char format [,argument] … );
不过sprintf_s()是微软私有的函数,考虑到跨平台移植,最好使用snprintf()
**int _snprintf(char buffer, size_t count, const char format [,argument] … );

###strftime
专门用于格式化时间字符串
要调用者指定缓冲区的最大长度
例:strftime(s, sizeof(s), “%Y-%m-%d %H:%M:%S”, localtime(&t));

输入密码无回显

#include <stdio.h>
#include <conio.h>
int main(void)
{
	int i = 0;
	char password[25],ch;
	printf("Please input password:");
	while(1){
		ch = getch();
		if(ch == '\r')
			break;
		password[i++] = ch;
	}
	password[i] = 0;
	printf("\nYour password is:%s\n",password);
	return 0;
}

运行结果

输入密码回显‘*’

#include <stdio.h>
#include <conio.h>
void in_password(char*,int,int);
int main(void)
{
	int min_len = 6, max_len = 16;
	char password[25],ch;
	printf("Please input password:");
	in_password(password, min_len, max_len);
	printf("\nYour password is:%s\n", password);
	return 0;
}
void in_password(char *password,int min,int max)
{
	int i;
	char ch;
	while(1){
		i = 0;
		while(1){
			ch = getch();
			if(ch == '\r')
				break;
			else if(ch == '\b'){
                if(i > 0){
                    printf("\b \b");
                    i--;
                }
                continue;
			}
			printf("*");
			if(i > max)
				break;
			password[i++] = ch;
		}
		password[i] = 0;
		if(i < min || i > max)
			printf("\nPlease input again:");
		else
			break;
	}
}

运行结果

<think>好的,我现在需要在C语言中实现输入密码示星号的功能。用户提到可以参考引用[1]中的代码,我得仔细看一下。那个例子里的hidden_input函数用了getch来获取输入,然后处理退格键和示星号。首先,我需要确定getch函数的使用方法,因为这在标准库中可能不可移植,可能需要conio.h或者类似的头文件,尤其是在Windows环境下。 然后,退格键的处理是关键。当用户按下退格键,需要将光标退,删除之前示的星号,且调整存储密码的数组。代码中检查input_char是否为'\b',如果是的话,判断index的位置。如果index>0,就执行退格操作,用putchar('\b')移动光标,再输出空格覆盖原来的星号,然后再退格一次,保持光标位置正确,同减少index。这部分逻辑需要仔细处理,避免数组越界。 接下来是普通字符的处理,每输入一个字符就打印一个星号,同将字符存入pwd数组,递增index。循环直到遇到车键'\r',这候在数组末尾加上结束符'\0'。需要注意的是,不同系统的换行符可能不同,Windows是'\r\n',而Linux通常是'\n',所以可能需要根据环境调整判断条件。 另外,代码中用了fflush(stdin)来清除输入缓存,但根据C标准,fflush仅用于输出流,输入流的fflush行为是未定义的,可能在有些编译器上不起作用。可能需要寻找替代方法,比如循环读取直到缓冲区清空,或者使用其他方式确保输入缓冲区干净。 还有,密码存储的安全性也要注意,比如防止缓冲区溢出。需要确保输入的字符数不超过pwd数组的长度,或者在代码中加入长度检查,避免溢出。例如,当index达到数组大小不再接受更多字符。 可能的问题:如果用户输入超过数组长度怎么办?原代码中没有处理这种情况,可能导致溢出。所以需要在输入字符检查index是否小于数组的最大长度减一(因为要留位置给结束符)。例如,当输入字符,只有index < max_length -1才允许存入数组,否则忽略输入或发出提示。 此外,getch函数在非Windows平台可能需要自己实现,或者使用其他函数如getchar,但这样可能需要处理回显的问题。这可能影响代码的可移植性。如果用户是在Windows下开发,使用conio.h的getch是可行的,但在Linux下可能需要其他方法,比如使用termios库来控制终端设置,禁用回显。 总结步骤: 1. 使用getch逐个读取字符,不回显。 2. 处理普通字符:示*,存入数组。 3. 处理退格键:删除前一个字符,调整光标和数组。 4. 处理车键结束输入。 5. 添加结束符,确保字符串正确终止。 6. 处理输入长度限制,防止溢出。 现在需要把这些步骤转化为代码,注意潜在的问题,比如缓冲区溢出、跨平台兼容性等。可能还需要测试不同情况下的退格操作,比如在密码为空按退格是否出错,输入过长处理是否正确。 另外,用户提供的引用[1]中的代码在退格处理有个条件判断:if(index <0) continue; 但index初始是0,输入退格,如果index是0,可能不会执行任何操作,所以这个条件可能多余。比如当index=0,用户按退格,此index--会导致index变成-1,但原代码中在退格处理会先检查index是否>0,所以当index=0不会执行退格操作,因此index不会变成负数,所以原代码中的if(index <0)可能是冗余的,可以去掉。 最后,确保在输入结束后,数组正确终止,没有内存泄漏或越界访问。</think>在C语言控制台中实现密码输入示星号(*)功能,可以通过以下步骤实现: ### 实现步骤 1. **使用`getch()`函数回显输入** 需包含`conio.h`头文件(仅限Windows系统),通过循环读取单个字符实现无回显输入。 2. **处理退格键(Backspace)** 当检测到退格键`\b`,需执行: - 光标左移一位 - 用空格覆盖原字符 - 光标再次左移一位 - 同调整密码缓冲区索引 3. **添加字符串终止符** 输入结束添加`\0`保证字符串合法性。 ```c #include <stdio.h> #include <conio.h> // Windows特有头文件 void get_password(char* pwd, int max_len) { char ch; int index = 0; while ((ch = getch()) != '\r') { // 车键结束输入 if (ch == '\b') { // 退格键处理 if (index > 0) { printf("\b \b"); // 擦除星号 index--; } } else if (index < max_len - 1) { // 防溢出 printf("*"); pwd[index++] = ch; } } pwd[index] = '\0'; // 字符串终止符 } ``` ### 关键细节说明 1. **跨平台兼容性** `conio.h`是Windows特有库,Linux/macOS需使用`termios.h`实现类似效果[^1]。 2. **缓冲区溢出防护** `index < max_len -1`确保存储空间足够容纳终止符。 3. **退格键逻辑优化** 使用`printf("\b \b")`替代三次`putchar`调用,代码更简洁。 ### 使用示例 ```c int main() { char password[20]; printf("请输入密码:"); get_password(password, sizeof(password)); printf("\n实际密码:%s", password); return 0; } ``` ### 注意事项 - 输入过程中按`ESC`键终止等高级功能需扩展实现 - 建议结合`memset`清空敏感内存区域提升安全性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值