自制 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]