2017-04-16 16 views
0

私のプログラムの単純な検証ユーザー名とパスワードを作成しようとしています。 私は確信していただきました私のコードで間違っていないけど、私はここにいくつかの論理エラーC++検証ログインコード

を持っていると思うことは、コード

  string usernameinput,passinput; 
string username[]={"mmm","nnnn","rrrr","aaa"}; 
string password[]={"1234","1212","1234","1212"}; 
bool flag=false; 

while(flag==false){ 
    cout << "username: "<<endl; 
    cin>>usernameinput; 
    cout << "password: "<<endl; 
     cin>>passinput; 
     for(int i=0;i<=3;i++){ 
      if(usernameinput ==username[i] && passinput==password[i]) 
      { 
       flag=true; 
      } 
      else if (usernameinput !=username[i] && passinput!=password[i]) 
      { 
       flag=false; 
    cout<<"please enter correct username and password"<<endl; 
      } 

     } 
} 
+0

:というよりも、自分の配列にパスワードとユーザー名を分離するには、グループにそれらをペアリング構造を使用し、唯一の配列を持っています。帳簿の節約が必要です。 – user4581301

答えて

0

の私の作品は、あなたがelseで十分で、二if文は必要ありませんです。たとえそれを保持しても、||ではなく&&でなければなりません。これは、一致しないものがフラグをfalseに設定するケースであるためです。

実際、elseという文も必要ありません。 falseにフラグを初期化しているので、に設定されるまではfalseのままになります。これは、ユーザー名とパスワードが一致する場合にのみ発生します。一致したら、比較を止めたいので、を使用してforループを終了させる必要があります。エラーメッセージは、すべての値をチェックするまで表示されないように、forループの外側にある必要があります。

bool flag=false; 

while(flag==false){ 
    cout << "username: "<<endl; 
    cin>>usernameinput; 
    cout << "password: "<<endl; 
    cin>>passinput; 
    for(int i=0;i<=3;i++){ 
     if(usernameinput ==username[i] && passinput==password[i]) 
     { 
      flag=true; 
      break; 
     } 
    } 
    if(!$flag) { 
     cout<<"please enter correct username and password"<<endl; 
    } 
} 
0

問題

プログラムは、一致が検出された後、一致の検索を停止しません。試合後にテストされた値は一致しないので、混乱が続く。今

if("mmm" == "mmm" && "1234" == "1234") // both true. Enter 
    { 
     flag=true; // flag is now true 
    } 
    else if ("mmm" != "mmm" && "1234" != "1234") 
    { 
     flag=false; 
     cout<<"please enter correct username and password"<<endl; 
    } 

for(int i=0;i<=3;i++){ 
    if(usernameinput ==username[i] && passinput==password[i]) 
    { 
     flag=true; 
    } 
    else if (usernameinput !=username[i] && passinput!=password[i]) 
    { 
     flag=false; 
     cout<<"please enter correct username and password"<<endl; 
    } 
} 

反復1:我々はMMMとユーザー名とパスワードの、それぞれの入力のために次のコードを実行したときに起こる

レッツ・ウォッチプログラムに一致が見つかったことを示すものは何もないので、探しを止めることができます。繰り返し2に進みます:

出力は、資格情報が正しい場合でも、flagはfalseになり、ユーザーはfalse negativeに3回警告されます。ヤック

please enter correct username and password 
please enter correct username and password 
please enter correct username and password 

マッチしたときにループを終了する必要がありました。明白な解決策は次のようなものです:

if(usernameinput ==username[i] && passinput==password[i]) 
    { 
     flag=true; 
     break; 
    } 

しかし、待ってください!もっとたくさん!入力がmmmとの場合はどうなりますか?

反復1:

if("mmm" == "mmm" && "1235" == "1234") //Second case fails 
    { 
     flag=true; 
     break; 
    } 
    else if ("mmm" != "mmm" && "1234" != "1234") // first case fails 
    { 
     flag=false; 
     cout<<"please enter correct username and password"<<endl; 
    } 

我々はいずれかの場合は入力しないでください。 flagは偽のままで、侵入者は侵入しませんが、これはちょっと醜いように見えますが、3つのエラーメッセージが表示されます。私たちはより良いことができます。

ソリューション

機能を作成します。

bool checkcredentials(const std::string & uname, 
        const std::string & pword) 
{ 
    bool rval = false; 
    for(int i=0;i<=3;i++) 
    { 
     if(uname== username[i]) 
     { 
      if (pword==password[i]) 
      { 
       rval = true; // could just return true here, but some folk get uptight 
          // over multiple returns in a function 
      } 
      break; 
     } 
    } 
    return rval; 
} 

呼び出し関数は、チェック・パスワード機能は何もしないことを

if (checkcredentials(usernameinput, passinput)) 
{ 
    // let the user in. 
} 
else 
{ 
    cout<<"please enter correct username and password"<<endl; 
} 

ノートのようなものがありませんが、資格情報を確認してください。ユーザーとのコミュニケーションはすべて他の場所で行われます。これにより、関数は単純なままになります。それは一つのことだけを行い、それは関数名で記述されるものです。

セキュリティ上の注意:ユーザーにメッセージを返す前に、少し時間がかかります。これは、レスポンスを計時することによって、資格情報のサイズまたは資格データベースのサイズを推測しようとしている人の頭部と混乱します。

これは、ユーザー名とパスワードをペアにしてアレイを1つだけ設定することで、さらにクリーンアップすることができます。これにより、ユーザー名がパスワードと一致し、パスワードを追加せずにユーザー名を追加したユーザーはいません。

pair<string, string> credentials[]={ // array of pairs 
    {"mmm", "1234"}, 
    {"nnnn", "1212"}, 
    {"rrrr", "1234"}, 
    {"aaa", "1212"} 
}; 

bool checkcredentials(const std::string & uname, 
         const std::string & pword) 
{ 
    bool rval = false; 
    for(auto & cred: credentials) 
    { 
     if(uname == cred.first) 
     { 
      if (pword == cred.second) 
      { 
       rval = true; 
      } 
      break; 
     } 
    } 
    return rval; 
} 

Documentation on pair.

そして、これは、よりスマートなデータ構造を改善することができます。 mapは、キー、ユーザー名に基づいてこの例では値、パスワードを参照する関連コンテナです。

オフトピック
map<string, string> credentials={ 
    {"mmm", "1234"}, 
    {"nnnn", "1212"}, 
    {"rrrr", "1234"}, 
    {"aaa", "1212"} 
}; 

bool checkcredentials(const std::string & uname, 
         const std::string & pword) 
{ 
    auto cred = credentials.find(uname); // look for user name 
    if (cred != credentials.end() && // username exists 
      cred->second == pword) // password matches 
    { 
     return true; 
    } 
    return false; 
} 

Documentation on map.