Итак, я должен зашифровать свое консольное приложение паролем, я сделал что-то, что работает, но есть проблема, backsapce не стирает введенный символ, он также считается за символ, как я могу заставить его выполнять свою работу , чтобы стереть символ?
Это код:
void main()
{
char password[20], my_password[20] = "password";
int i;
char ch;
system("cls");
cout << "PASSWORD: ";
i = 0;
do
{
ch = _getch();
password[i] = ch;
if (ch != 27 && ch != 13 && ch != 9)
cout<<"*";
else
break;
i++;
} while (i < 19);
password[i] = '\0';
if (strcmp(password, my_password) != 0)
{
cout << "\n\nIncorrect password !!!";
cin.get();
return;
}
cout << "\n\nPassword is correct !";
cout <<"\n\nThe program is executed !";
cin.get();
}
Пожалуйста, не используйте магические числа. Для символов, у которых есть escape-последовательности (например, 13
для возврата каретки, '\r'
), используйте эти символы, а для символов, у которых нет escape-последовательностей (например, 27
и 9
), по крайней мере, создайте макросы.
Также обратите внимание, что _getch
` возвращает int
, как и все стандартные функции чтения символов. Это довольно важно, если вы когда-нибудь захотите сравнить с EOF
.
Наконец, пожалуйста, не добавляйте теги для языков, которые могут показаться похожими, используйте только теги для языка, на котором вы на самом деле программируете. C и C++ — это два очень разных языка. И хотя вы не используете многие функции C++, ваша программа по-прежнему является программой C++, поэтому не должна иметь тега c
.
"как я могу заставить его делать свою работу, чтобы стереть характер?"
Используйте библиотеку curses
. Например, ругает.
Не вмешивайтесь ncurses
без необходимости; это инструмент для конкретной области, и для таких простых вещей, как этот, он в лучшем случае перегружен.
@Ctx Краткосрочный; может быть. Но как только OP захочет делать более сложные вещи, библиотека curses
станет удобной (и она также может решить насущную проблему).
Вы можете проверить, является ли полученный символ возвратом, если это декремент i
, который эффективно удалит последний символ.
i = 0;
do
{
ch = _getch(); // get the character
if (ch == DEL || ch == BS) // check for backspace
{
i--;
cout << BS;
}
else if (ch >= ' ' && ch <= '~') // check if its valid ASCII
{
password[i] = ch;
cout << "*";
i++;
}
else if (ch == 27 || ch == 13 || ch == 9) // check if entry is complete
{
break;
}
} while (i < 19);
password[i] = '\0';
где-нибудь еще
#define BS '\b'
#define DEL 127
Вместо макросов, которые могут разрушить хаос подстановки текста, рассмотрите возможность использования чего-то вроде constexpr char BS = '\b';
. Это не будет молча топтаться по BS
s, а будет рассматриваться как char
, позволяющее компилятору ввести проверку и сделать все остальные сообщения об ошибках и предупреждениях. макрос не может, а '\b'
позволяет переносимость на системы, отличные от ASCII (меньше беспокойства, чем раньше, но все же на что следует обратить внимание).
Спасибо за дополнение, вы правы с общим улучшением использования экранированного символа, а не целого числа. Я изменил макрос на '\b', но пока оставлю его как макрос. Я работаю только с C, я думаю, что OP не должен был помечать C, так как это действительно должен быть только C++.
Я даже не видел тег C. Ты прав. Я удалю этот тег через секунду.
void main()
{
char password[20], my_password[20] = "password";
int i;
char ch;
system("cls");
cout << "PASSWORD: ";
i = 0;
do
{
ch = _getch();
if (ch == 8)
{
i--;
cout << "\b \b";
continue;
}
password[i] = ch;
if (ch != 27 && ch != 13 && ch != 9)
cout << "*";
else
break;
i++;
} while (i < 19);
password[i] = '\0';
if (strcmp(password, my_password) != 0)
{
cout << "\n\nIncorrect password !!!";
cin.get();
return;
}
cout << "\n\nPassword is correct !";
cout << "\n\nThe program is executed !";
cin.get();
}
Не самый чистый код, но он работает. Уменьшите значение счетчика, чтобы перезаписать предыдущий символ, и выведите два символа возврата, разделенные пробелом.
Рекомендуем прочитать перед использованием этого ответа: Что такое магическое число и почему оно плохое?
Какой тип терминала и операционной системы вы используете?