2016-09-25 3 views
1

이 C++ 프로그램에서 사용자 이름과 암호 (마스크 된)를 받아들이고 미리 값과 비교합니다. 동일하면 프로그램이 닫히고 그렇지 않으면 처음으로 돌아갑니다.
나는 패스워드 입력에 어려움을 겪었습니다. 특히 일반적인 입력을 흉내내는 것과 같이. 지금까지 나는 Enter와 Backspace 기능을 넣을 수 있었지만, 나는 단지 화살표 키를 얻는 것 같지 않다.
아래 코드를 사용하면 프로그램이 부분적으로 올바르게 작동하고 물론 왼쪽 키를 누를 때 커서가 두 번 뒤로 이동합니다. 그러나이 과정에서 현재의 문자를 '알파'기호와 이전 문자를 'K'로 바꿉니다. (K와 서로 옆에있는 알파 기호는 내 컴파일러 dev C++가 왼쪽 화살표 키와 연결하는 값인 것 같습니다.
또한 '\ b'를 제거하면 커서가 전혀 움직이지 않습니다. 또한 이전 문자를 'K'로 대체합니다. 나는 지금해야할 일을 모른다. 그래서 나는 너에게 묻는다. 미리 감사드립니다! 당신이 특수 키를 누르면암호 입력시 커서 이동 C++

#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

코드를 정리해야한다고 생각합니다. 왜냐하면 많은 것들이 의미를 갖지 않기 때문입니다. 예를 들어'i'를'0'으로 설정하는 대신'while (i! = 0) {-i;} '를 실행하는 이유는 무엇입니까? 또한, 처음에는 'i'를 0으로 설정 한 직후 'i + 1'크기의 배열을 만드는 이유는 무엇입니까? 'char parr [i + 1]'는 크기가 1 인 배열'parr'을 선언합니다. 따라서 나중에'parr [i] = ... '를 실행하면 메모리가 손상 될 수 있습니다. 더욱이,'parr'과 패스워드의 비교는 결코 사실이 아니며 "Welcome!" –

+0

@ThomasWilmotte 프로그램은 전체 getasynckeystate 행 없이는 저를 위해 정상적으로 실행됩니다. –

답변

1

두 바이트는 프로그램에 전송된다 (화살표 키 등을 , , ... 삭제). 이 경우 왼쪽 키를 누르면 0xe00x4b 바이트가 전송됩니다. 두 번째 값은 ASCII 테이블의 K 문자에 해당하며 첫 번째 문자는 확장 ASCII 테이블의 버전에 따라 다릅니다 (α 일 수도 있고 à 일 수 있음).

문제는 루프에서 왼쪽 키가 눌러져 있는지 확인하는 것입니다. 이 경우 출력 스트림의 커서를 왼쪽으로 두 번 이동하여 (\bstd::cout으로 전송) 프로그램을 정상적으로 실행하면서 가지고있는 문자와 다음 문자 (예 : 0xe00x47)를 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 

왼쪽 키를 누르거나 출력을 변경하지 않지만 인덱스를 변경하지 여부.

+0

그 잘 설명 된 답변을 주셔서 대단히 감사합니다! –

+0

Hey @Thomas Wilmote 방금 출력물을 확인했는데, 당신이 말한 것과 조금 다르게 보입니다. 또한, 당신과 공유하고 싶은 많은 관찰이 있습니다. (나는 또한 당신이 사물을 설명하는 방법에 대해 큰 감명을 받았다.) 그리고 내가 여기에 그 모든 것을 말할 수 없기 때문에, 우리가 다른 곳에서 이야기 할 수 있을지 궁금해. 페이스 북이나 행 아웃과 같습니다. –

+1

다른 방안에 대해 이야기하기 위해이 방을 http://chat.stackoverflow.com/rooms/124411/solving-a-problem-with-anchith-acharya에 초대합니다. 나는 거기 머물러 새로운 메시지를 수시로 게시했는지 확인합니다. –