2012-11-10 117 views
1

我一直在解決這個問題無數小時,我找不到問題所在。我改變並測試了問題的每個部分,並總是得到奇怪和錯誤的結果。我開始認爲,也許我的編譯器出現故障。從C++開始,密碼驗證程序

這就是我想要做的: 開發一個程序,提示輸入密碼,程序檢查是否滿足以下條件。

最少6個字符長。

至少包含一個大寫字母。

至少包含一個小寫字母。

包含至少一個數字。

如果輸入的密碼不符合標準,則程序應顯示原因並提示重新輸入。如果密碼是好的,它會顯示一條消息並結束程序。請幫忙!

注意:這是一個控制檯32程序。

#include "stdafx.h" 
#include <iostream> 
#include <cstring> 
#include <cctype> 
#include "ctype.h" 
using namespace std; 

// Function prototype 
bool lengthTest(char *); 
bool lowCaseTest(char []); 
bool upCaseTest(char []); 
bool digitTest(char []); 
const int SIZE = 20; 

int main() 
{ 
    // Buffer to hold the string. 
    char password[SIZE]; 
    int sumofbool; 
    // Program Intro Display 
    cout << "----PASSWORD VERIFIER PROGRAM----\n\n"; 
    cout << "Enter a password that meets the following criteria:\n" 
    << "-Minimum of 6 characters in length.\n" 
    << "-Contains at least one uppercase and one lowercase letter.\n" 
    << "-Contains at least one digit.\n\n"; 
    cout << "->"; 
    // Get input from user. 
    cin.getline(password, SIZE); 

    sumofbool = lengthTest(password) + lowCaseTest(password) + upCaseTest(password) 
    + digitTest(password); 
    // if 1 or more of the 4 functions is not true, display why and prompt for re-entry. 
    while (sumofbool < 4) 
    { 
     if (!lengthTest(password)) 
     cout << "Error, password must be at least 6 characters long.\n"; 

     if (!upCaseTest(password)) 
     cout << "Error, password must contain at least one upper case letter.\n"; 

     if (!lowCaseTest(password)) 
     cout << "Error, password must contain at least one lower case letter.\n"; 

     if (!digitTest(password)) 
     cout << "Error, password must contain at least one digit.\n"; 

     cout << "Please re-enter password: "; 
     // prompt for re-entry and call functions to test input. 
     cin.getline(password, SIZE); 
     sumofbool = lengthTest(password) + lowCaseTest(password) + upCaseTest(password); 
     + digitTest(password); 
    } 
    // if conditions for password are met, display message. 
    cout << "\nYou entered a valid password.\n\n"; 

    return 0; 
} 

//*********LENGTH TEST FUNCTION*********** 
bool lengthTest(char *str) 
{ 
    int numChar = 0; 
    bool validlength = false; 
    for (int cnt = 0; cnt < SIZE; cnt++) 
    { 
     while (*str != 0) 
     str++, numChar++; 
    } 
    if (numChar >= 6) 
    validlength = true; 

    return validlength; 

} 
//*********LOWERCASE LETTER TEST FUNCTION********* 
bool lowCaseTest(char pass[]) 
{ 
    for (int cnt = 0; cnt < SIZE; cnt++) 
    { 
     if (islower(pass[cnt])) 
     return true; 
    } 
    return false; 
} 
//********CAPITAL LETTER TEST FUNCTION********* 
bool upCaseTest(char pass[]) 
{ 
    for (int cnt = 0; cnt < 20; cnt++) 
    { 
     if (isupper(pass[cnt])) 
     return true; 
    } 
    return false; 
} 
//**********DIGIT TEST FUNCTION************ 
bool digitTest(char pass[]) 
{ 
    for (int cnt = 0; cnt < 20; cnt++) 
    { 
     if (isdigit(pass[cnt])) 
     return true; 
    } 
    return false; 
} 
+1

*我開始想,也許我的編譯器出現故障*幾乎總是表明您有故障,現在是時候散步或睡一覺了。 – Duck

+0

給出它失敗的例子。這將很容易反向工程。 – Mahesh

+5

我有一種感覺,它有一些事實,即程序正在測試傳入的每個字符串中的SIZE字符,但不保證該字符串是SIZE字符長。這應該真的停止測試一旦達到NULL字符,否則我會想象你應該期待未定義的行爲。 – BenTrofatter

回答

1

你必須在線路

sumofbool = lengthTest(password) + lowCaseTest(password) + upCaseTest(password); 
+ digitTest(password); 

一個額外的分號(哇,這花了一段時間發現。)要解決這個應該可以解決問題的長度。

我也認爲,線:

for (int cnt = 0; cnt < SIZE; cnt++) 
{ 
    while (*str != 0) 
    str++, numChar++; 
} 

可以縮短到僅僅

while (*str != 0) 
str++, numChar++; 

,雖然這不會改變功能。前者只計算長度,然後對於SIZE - 1迭代沒有任何作用。

此外,由於BenTrofatter在評論中提到,您每次測試字符串時都會檢查SIZE字符數量。如果字符串比SIZE短,則不知道在字符串長度之後要訪問的內存。

由於您將此標記爲C++,因此我會說C++字符串是MarceloCantos提到的。通常,從傳遞參數到訪問子字符串,它們更容易處理。

0
  1. 不要試圖總結布爾值
  2. 取代不管你有lengthTest()與簡單的調用strlen(str)
  3. 無處不在,你在一個循環訪問字符串,請使用strlen()作爲循環終止的條件,沒有任何你有沒有馬上
  4. 不使用while (*str != 0) str++硬編碼的價值 - 這是會咬你的屁股逃跑指針和內存損壞每次發出的循環
  5. 使用變量I,J,K - 這是標準的C/C++

也,我肯定會用這樣的單次運行更換多個運行在相同的字符串:

bool has_uppers = false, has_lowers = false, has_digits = false; 

int length = strlen(password); 
for(int i=0; i<length; i++) { 
    char ch = password[i]; 
    has_uppers |= isupper(ch); 
    has_lowers |= islower(ch); 
    has_digits |= isdigit(ch); 
}