Functions not working as intended

None of my functions save for the one that compares the user password to the text file seems to be working as intended, what am I doing wrong?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  #include <iostream>
#include <string>
#include <fstream>

using namespace std;

bool search(string key, string list[], int size);
bool searchspace(string key);
bool searchlength(string key);
bool searchuppercase(string key);
bool searchnumber(string key);
bool searchspecial(string key);


int main()
{
	int i = 0;
	char againAgain = 'y';
	const int MAXPASSWORD = 4000;
	string userpassword;
	string commonPasswords[MAXPASSWORD];
	std::ifstream passWordFile;
	passWordFile.open("passwords.txt");
	if (!passWordFile) 
	{
		std::cout << "Error!";
		exit(1);
	}

	while (!passWordFile.eof())
	{
		passWordFile >> commonPasswords[i];
		i++;
	}

	int count = i;

	cout<< "\n Rules to follow when creating a password:" << endl;
	cout<< " 1. No spaces.\n"
		<< " 2. Must use at least one captial letter.\n"
		<< " 3. Must use at least one number. \n"
		<< " 4. Must use ! $ % or ? \n"
		<< " 5. Password must be 8 or more characters long. \n";

	do{//The do loop allows the user to run the program
		//again with out exiting the program prematurely.
		cout << "\n\n User Please Enter Your Password: ";
		getline (cin,userpassword);

		bool spaceResult = searchspace(userpassword);
		bool lengthResult = searchlength(userpassword);
		bool uppercaseResult = searchuppercase(userpassword);
		bool numberResult = searchnumber(userpassword);
		bool specialResult = searchspecial(userpassword);
		bool found = search(userpassword, commonPasswords, count);

		if (spaceResult == false && lengthResult == true &&
			uppercaseResult == true && numberResult == true &&
			specialResult == true && found == false)
		{
			cout<< "\n Good. Password meets all requirement."
				<< endl;
			againAgain = 'n';
		}
		else//this allows the program to let the user know
			//what requirements were not met, whenever the
			//above if statement has not been proven true?
		{
			if (spaceResult)
				cout << "\n Password must not contain spaces.";
			if (!lengthResult)
				cout << "\n Password must be eight characters"
				<< " or more.";
			if (!uppercaseResult)
				cout << "\n Password must contain at least"
				<< " one captial letter.";
			if (!numberResult)
				cout << "\n Password must contain at least"
				<< " one number.";
			if (!specialResult)
				cout << "\n Password must contain at least"
				<< " one of the \n following characters: "
				<< "! $ % or ?.";
			if (found)
				cout << "\n Password is too common.";
		}

	} while (againAgain == 'y');
	cout << endl << endl;
	return 0;
}

//This is the function that detects spaces in the user's
//entered password.
bool searchspace(string key)
{
	bool ans = key.find(' ');
	if (ans == true)
	{
		return true;
	}
	return false;
}

//This is the function that checks the user's password
//to make sure it is at least eight characters or more.
bool searchlength(string key)
{
	int ans = key.length();
	if (ans >= 8)
		return true;
	else return false;
}

//This is the function that makes sure that there is at
//least one captial letter in the user's password.
bool searchuppercase(string key)
{
	bool ans = key.find('A' || 'B' || 'C' || 'D' ||
		'E' || 'F' || 'G' || 'H' || 'I' ||
		'J' || 'K' || 'L' || 'M' || 'N' ||
		'O' || 'P' || 'Q' || 'R' || 'S' ||
		'T' || 'U' || 'V' || 'W' || 'X' ||
		'Y' || 'Z');
	if (ans == true)
	{
		return true;
	}
	else return false;
}

//This is the function that looks for at least one
//numerical character in the user's password.
bool searchnumber(string key)
{
	if (key.find('1' || '2' || '3' || '4' ||
		'5' || '6' || '7' || '8' || '9' ||
		'0'))
		return true;
	else return false;
}

//This is the function that sends back true or false on
//whether the user's password contains one of the four
//special characters stated in the rules.
bool searchspecial(string key)
{
	if (key.find('!' || '$' || '%' || '?'))
		return true;

	else return false;
}

//This function compares the user's password with the
//loaded file of common passwords.
bool search(std::string key, std::string list[], int size)
{
	for (int i = 0; i <= size; i++)
	{
		if (key.find(list[i])>-1)
			return true;
	}
	return false;
}
95
96
97
98
99
100
101
102
103
bool searchspace(string key)
{
    bool ans = key.find(' ');
    if (ans == true)
    {
        return true;
    }
    return false;
}

The find member function doesn't return a bool indicating whether or not the character was found -- it returns the position of the first occurrence, or std::string::npos if it wasn't found.
So it should be
1
2
3
4
if (key.find(' ') != string::npos)
    return true; // We found a space
else
    return false;
or, more simply,
return key.find(' ') != string::npos;.

Now, for your other functions:
117
118
119
120
121
122
123
124
bool searchuppercase(string key)
{
    bool ans = key.find('A' || 'B' || 'C' || 'D' ||
        'E' || 'F' || 'G' || 'H' || 'I' ||
        'J' || 'K' || 'L' || 'M' || 'N' ||
        'O' || 'P' || 'Q' || 'R' || 'S' ||
        'T' || 'U' || 'V' || 'W' || 'X' ||
        'Y' || 'Z');

This part doesn't do what you think it does.
It evaluates 'A' || 'B' || /* ... */ || 'Z' (which turns out to be true since those values are non-zero), and then calls find with the result.
So you basically get
bool ans = key.find(true);, or in other words, you're searching for a character whose value is true (probably 1 or something).

To fix this, use find_first_of instead of find:
1
2
3
4
5
string::size_type pos = key.find_first_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
if (pos != string::npos)
    return true; // We found an uppercase letter
else
    return false;
(or, more simply, just return key.find_first_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ") != string::npos;).

Same with your other functions.

Now, for your search function, instead of
if (key.find(list[i])>-1), I would suggest you write

if (key.find(list[i]) != string::npos).

(I think if (key.find(list[i]) > -1) will always be true anyways, since you're comparing an unsigned integer, which is always positive, with -1.)

600!
Last edited on
Oh thats why it didn't work. I figured it would work similar to a bool so i used it like one, silly me.

npos seems to do the trick for all my functions but now the search function does not work at all. whether I use my original code or the one you suggested. I'm guessing it had never worked and I was just fooling myself :(.

Again this worked wonders, but I'm having trouble understand how it works:
return key.find_first_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ") != string::npos;
Again this worked wonders, but I'm having trouble understand how it works:
return key.find_first_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ") != string::npos;

It's the same thing as
1
2
3
4
5
string::size_type pos = key.find_first_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
if (pos != string::npos)
    return true;
else
    return false;
.
Oh, and if you were wondering what find_first_of does:
http://www.cplusplus.com/reference/string/string/find_first_of/

Also, when reading from your file:
1
2
3
4
5
while (!passWordFile.eof())
{
    passWordFile >> commonPasswords[i];
    i++;
}

Don't loop on eof(). The problem with looping like that is that the EOF flag doesn't actually get set until you try to read past the end of the file -- that is, right when you've read the last password and there's technically nothing else in the file to read, the EOF flag still won't be set until the next iteration, when you try to read from the file again and it fails.

So instead, loop while you can still get input successfully:
1
2
3
4
while (passWordFile >> commonPasswords[i])
{
    i++;
}

Then, in your search function, instead of
for (int i = 0; i <= size; i++), it should be

for (int i = 0; i < size; i++) (< instead of <=).
Last edited on
I think that did the trick. Also thank you for that link, it explained what I wanted to know. I should bring the eof() thing up with my teacher, it seems like a bad habit to learn. That and pause.

Welp, off to work on part three of this project. Deciding on whether the password that pass the test is weak, medium, or strong. Then part four, GUI. Wish me luck ^_^, and again, Thank you for you help and the link.
Topic archived. No new replies allowed.