Движение курсора при вводе пароля c ++ \

У меня есть эта программа C ++, чтобы принять имя пользователя и пароль (который маскируется) и сравнить их с заданными значениями. Если они совпадают, программа закрывается, в противном случае она возвращается к началу.
У меня были некоторые трудности с вводом пароля, особенно при имитации обычного ввода. До сих пор мне удавалось использовать функциональность Enter и Backspace, но я просто не могу понять, как правильно использовать клавиши со стрелками.
С помощью приведенного ниже кода программа работает частично вправо, и, конечно, при нажатии левой клавиши курсор перемещается назад два раза. Но в процессе он также заменяет текущую букву, под которой он находится, символом «альфа», а предыдущую букву буквой «K». (Кажется, что K и буквенный символ рядом друг с другом — это значение, которое мой компилятор, dev c ++ связывает с левой стрелкой)
Кроме того, когда я удаляю лишнюю ‘\ b’, курсор просто не двигается вообще, а также заменяет предыдущую букву на ‘K’. Я не знаю, что делать сейчас, поэтому я вас спрашиваю. Заранее спасибо!

#include <stdlib.h>
#include <conio.h>
#include <iostream.h>
#include <windows.h>

using namespace std;
int main()
{
int i=0;string u;char parr[i+1],ch;

while (1)
{
system("cls");
cout<<"Enter username."<<endl;
cin>>u;

system("cls");
cout<<"Enter password."<<endl;
i=0;

while (1)
{
ch=getch();
if (ch=='\r') break;

if (GetAsyncKeyState(VK_LEFT)) cout<<'\b'<<'\b';

if (ch=='\b')
{
cout<<'\b';
while (i!=0) {--i;}
ch='\0';
parr[i]='\0';
cout<<' '<<'\b';
continue;
}

parr[i]=ch;
ch='*';
cout<<ch;
++i;
}

parr[i]='\0';
string p="password";

if (u=="username" && parr==p)
{
system("cls");
cout<<"Welcome!";
break;
}
else
{
system("cls");
cout<<"Username and password entered does not match! Please try again.";
}

getch();
}

getch();
}

1

Решение

Когда вы нажимаете специальный ключ (как клавиши со стрелками, удалять, Главная, …) два байта отправляются в вашу программу. В этом конкретном случае, когда вы нажимаете левую клавишу, байты 0xe0 а также 0x4b посланы. Второе значение соответствует K символ в таблице ASCII, и первый зависит от версии расширенной таблицы ASCII (может быть α но также à).

Ваша проблема в том, что в вашем цикле вы начинаете с проверки, нажата ли левая клавиша. Если это так, вы перемещаете назад курсор вашего выходного потока дважды влево (отправляя \b в std::cout), и вы продолжаете нормально выполнять свою программу, сохраняя полученный символ и следующие (так 0xe0 а также 0x47) в вашем parr массив. Графически вот что происходит:

Action      BYTE SENT           parr              Comment
PRESS a          0x61           > a
PRESS b          0x62           > ab
PRESS LEFT  0xe0 0x4b           > abα             The first update of parr (0xe0)
> αbαK            You enter directly in the loop
because there is another byte (0x4b)
waiting in the input stream
PRESS c          0x63           > αbαKc

На самом деле, поскольку ваша цель состоит в том, чтобы печатать звездочки вместо пароля, при нажатии левой клавиши вам не нужно перемещать курсор назад в консоли. Действительно, количество печатаемых символов остается неизменным, и, поскольку вы всегда печатаете один и тот же символ, печать следующего, начинающегося в конце строки консоли, даст тот же результат.

Однако, что вы должны сделать, когда нажата левая клавиша, это переместить указатель, чтобы указать, где в вашем parr массив следующих введенных символов должен быть вставлен.

Давайте рассмотрим, например, две следующие последовательности:

Pressing       Will display    parr     Pointer to the position
where to insert the new char
0
a              *               a        1
b              **              b        2
c              ***             abc      3

0
a              *               a        1
LEFT           *               a        0
b              **              ba       1
LEFT           **              ba       0
c              ***             cba      1

Независимо от того, нажали вы левую клавишу или нет, вы не меняете выход, а меняете индекс.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]