自制 C++ 密码程序(第二代)

自制 C++ 密码程序(第二代)

说明:第一代的基础上添加了一些功能
注意: 作者使用的是 linux 系统,windows和macos 用户直接编译可能会报错
某些地方是为 linux 准备的,如果你用windows系统,需根据注释修改
话不多说,上代码:

/*
更新:
	最一代:
		https://blog.csdn.net/linux_rm/article/details/123437812
	第二代:
		支持字符串
		按下F3,输入(新)
*/
// 作者使用的是 linux 系统,windows和macos 用户直接编译可能会报错
#include <termios.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
// 以上头文件为 linux 获取字符的 getch() 准备
// 如果你是 windows 系统,那么改成:
// #include<conio.h>
// 由于作者不熟悉 macos 系统,所以没有关于 macos 的注释,macos 用户需自行琢磨
#include <signal.h> // 检测键盘信号
#include <iostream> // C++必备头文件

using namespace std; // 命名空间std

// 初始化 (新)
std::string Word; // 定义字符串
char c = 0;		  // 定义字符

// 键盘错误 (新)
void err()
{
    
    
	std::cout << "\r\a\e[2K清重新输入:" << flush; // 响铃(主板蜂鸣器或系统播放声音)并清行并打印消息 (新)
	c = 0;										  // 清除字符 (新)
	Word = "\0";								  // 清除字符串 (新)
}

// Ctrl+C信号处理 (新)
void breakc(int sig)
{
    
    
	if (sig == SIGINT)
	{
    
    
		err(); // 键盘错误 (新)
	}
}

char getch() // linux 获取字符的 getch() ,windows 系统要直接删除这个函数
{
    
    
	//以下不是核心,我就少注释了
	char c = 0;
	struct termios org_opts, new_opts;
	int res = 0;
	//-----  store old settings -----------
	res = tcgetattr(STDIN_FILENO, &org_opts);
	assert(res == 0);
	//---- set new terminal parms --------
	memcpy(&new_opts, &org_opts, sizeof(new_opts));
	new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL);
	tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
	c = getchar();
	//------  restore old settings ---------
	res = tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
	assert(res == 0);
	// cout << (int)c << " , " << flush; // 测试编码
	return c;
}

std::string get() // //获取密码
{
    
    
	std::cout << "请输入:"; // 提示文字,可修改或删掉
	while (1)				// 循环
	{
    
    
		c = getch(); // windows系统可能要改为_getch()
		switch (c)	 //判断输入
		{
    
    
		case 4:									  // 获取Ctrl+D (新)
			std::cout << "\r\a\e[2K退出" << endl; // 打印信息
			exit(1);							  // 退出并返回1
			break;
		case 10:					   // 获取回车(linux中编码为10)
			if (Word.size())		   //字符串长度大于0
				std::cout << "  \r\n"; //输出"换行"
			return Word;			   //返回字符串并退出循环
			break;					   //退出判断
		case 127:					   // 获取退格(linux中编码为127)
			if (Word.size())
			{
    
    
				std::cout << "\b \b"; // 向左移动光标并删除屏幕上的一个字符串符号(替换成空格)
				Word.pop_back();	  // 删除字符串前一个字符
			}
			break;
		case 27:			   // (新) 获取 Esc,防止终端错误(Esc使用方法详情
							   // https://blog.csdn.net/linux_rm/article/details/124732456
			if (getch() == 91) // 获取'[' (新)
			{
    
    
				switch (getch()) // 再获取一次 (新)
				{
    
    
				case 65: //上 (新)
					std::cout << "\a";
					break;
				case 66: //下 (新)
					std::cout << "\a";
					break;
				case 67: //右 (新)
					std::cout << "\a";
					break;
				case 68: //左 (新)
					std::cout << "\a";
					break;
				default:
					err();
					break;
				}
			}
			else
			{
    
    
				err(); // 键盘错误(新)
			}
			break;
		default:				// 获取其他字符
			Word += c;			// 插入字符串
			cout << c << flush; // 显示字符,可修改或删掉(同时删掉 std::cout << "\b \b";)
			break;
		}
		c = 0;
	}
}

std::string out() // 输出时的动作 (新)
{
    
    
	std::string W = get();
	cout << "输入结果:"; // 打印信息
	return W;			 // 返回输入值(字符串)
}

int main(int argc, char const *argv[]) // 主函数
{
    
    
	signal(SIGINT, breakc); // Ctrl+C信号处理 (新)
	std::cout << out() << endl;
	return 0; // 正常时返回值为0
}

运行结果:
1234[Ctrl+C]abcd[退格]e[回车]
1234[Ctrl+D]
运行结果

猜你喜欢

转载自blog.csdn.net/linux_rm/article/details/125131533