2016-09-25 13 views
1

私はこのユーザー名とパスワード(マスクされている)を受け入れ、それらをプリセット値と比較するこのC++プログラムを持っています。それらが同じであれば、プログラムは終了し、それ以外の場合は最初にループバックします。
パスワードの入力に問題がありました。特に、通常の入力を模倣しました。これまでのところ、私はEnterとBackspaceの機能を追加することができましたが、私はちょうど矢印キーを正しく取得することはできません。
以下のコードでは、プログラムは部分的にうまく動作しますが、もちろん、左キーが押されるとカーソルが2回前に移動します。しかし、このプロセスでは、現在のアルファベットを 'アルファ'記号と前の文字を 'K'に置き換えます。 (Kと互いに隣り合っているアルファ記号は、私のコンパイラdevC++が左矢印キーと関連づけている値のようです)
また、余分な '\ 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'とパスワードとの比較は決して真実ではなく、「ようこそ! –

+0

@ThomasWilmotteこのプログラムは、getasynckeystate行全体がなくてもうまく動作します。 –

答えて

1

あなたは(矢印キーのような、を削除し、、...)特別キーを押すと2つのバイトは、あなたのプログラムに送信されます。この場合、左キーを押すと、0xe00x4bのバイトが送信されます。 2番目の値はASCIIテーブルのK文字に対応し、1番目は拡張ASCIIテーブルのバージョンに依存します(αでもàでも可能)。

あなたの問題は、ループの中で、左のキーが押されているかどうかをチェックすることです。その場合、出力ストリームのカーソルを左に2回移動して(\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配列のどこに次の入力文字を挿入する必要があるかを示すためにインデックスを移動することです。

はのは、例えば、2つの以下の配列を考えてみましょう:

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

ちょっと@Thomas Wilmote私はちょうど出力を確認し、あなたと言ったものと少し違っているようです。また、皆さんと分かち合うことがたくさんあります。 (私もあなたが物事を説明する方法でメガに感銘を受けています)そして、私はあなたにここでそれをすべて伝えることができないので、私はどこか他の人と話すことができるのだろうかと思います。 Facebookやハングアウトのように。 –

+1

私はあなたの他の問題について話すために、この部屋に来てください。http://chat.stackoverflow.com/rooms/124411/solving-a-problem-with-anchith-acharya私はそこにとどまり、あなたが時々新しいメッセージを投稿したかどうか確認します –

関連する問題