The Cellar  

Go Back   The Cellar > Main > Technology
FAQ Community Calendar Today's Posts Search

Technology Computing, programming, science, electronics, telecommunications, etc.

Reply
 
Thread Tools Display Modes
Old 11-21-2010, 09:20 PM   #1
Flint
Snowflake
 
Join Date: Mar 2006
Location: Dystopia
Posts: 13,136
C++ Help, Please. Thank You.

This program is supposed to check that a password is at least 6 characters AND contains at least one digit. What I never was able to figure out is how to check for BOTH conditions. Since I have them in two functions, once one is satisfied, it drops to the next one and forgets about the other. I didn't know how to get "back" to the previous condition, so I copy/pasted the code in an if/else statement! The if statement was originally supposed to print the "Thank you that is a valid password" but it didn't print, so I put it in again at the bottom.

However, if you put in a correct password at the first prompt, the if statement prints. In the version I am turning in, I told it to print an endl; (it just skips a line).

See how the "Please enter a password: ";s are numbered 1 through 4? if you get down to "Please enter a password4: "; and enter 123 it accepts this as valid. It still does not check "also" for length.

I don't know how to validate a string of input for two separate conditions. The problem is, when it fails I need it to tell the user why it failed, so I can't just lump them together.

I am going cross-eyed. Can anybody tell me what my ignorant mistake is?

There are no examples of this in my textbook...

Quote:
//This program prompts the user to enter a password,
//and then checks the password against (a) and (b)
//conditions to determine if it is valid. Whenever
//the password fails a checkpoint, the reason is given
//and the user is prompted to enter another password.
//When a correct password is given, the user is informed
//and the program exits anfter the enter key is pressed.

#include<iostream>
#include<cstring>
#include<cctype>
using namespace std;

//Function checks the password for length. (a)
bool passLength(char[]);

//Function checks the password for a digit. (b)
bool containDigit(char[]);

int main()
{
const int SIZE = 21;
char password[SIZE];

cout << "Please enter a password: ";
cin.getline(password, SIZE);

while (!passLength(password)) //(a) called
{
cout << "Passwords must be at least 6 characters long" << endl;
cout << "Please enter a password1: ";
cin.getline(password, SIZE);
(passLength(password)); //(a) called again
}

while (!containDigit(password)) //(b) called
{
cout << "Passwords must include at least on digit (1-9)" << endl;
cout << "Please enter a password2: ";
cin.getline(password, SIZE);
(containDigit(password)); //(b) called again
}

if ((passLength(password)) && (containDigit(password)))
{
cout << "Clearly, I have no idea what I'm doing here..." << endl;
cout << "I copy/pasted the previous code, to check it again. lol." << endl;
cout << "I never really figured out how to check for BOTH conditions."<< endl;
}
else
{
while (!passLength(password)) //(a) called
{
cout << "Passwords must be at least 6 characters long" << endl;
cout << "Please enter a password3: ";
cin.getline(password, SIZE);
(passLength(password)); //(a) called again
}

while (!containDigit(password)) //(b) called
{
cout << "Passwords must include at least on digit (1-9)" << endl;
cout << "Please enter a password4: ";
cin.getline(password, SIZE);
(containDigit(password)); //(b) called again
}
}

cout << "Thank you that is a valid password" << endl;

//Keep the window open until Enter key is pressed.
cout << "\nPress Enter to close window..." << endl;
std::cin.get();

return 0;
}

bool passLength(char password[]) //(a) function
{
int lengthPass = 6;
int length = strlen(password);

if (lengthPass <= length)
return true;
else return false;
}


bool containDigit(char password[]) //(b) function
{
int index = 0;
int length = strlen(password);

for (index = 0; index < length; index++ )
{
if (isdigit(password[index]))
return true;
}
return false;

}
I am a total n00b at programming, this is programming fundamentals 1. Please take pity on me. This is due on Nov. 23rd.
__________________
******************
There's a level of facility that everyone needs to accomplish, and from there
it's a matter of deciding for yourself how important ultra-facility is to your
expression. ... I found, like Joseph Campbell said, if you just follow whatever
gives you a little joy or excitement or awe, then you're on the right track.

. . . . . . . . . . . . . . . . . . . . . . . . . . Terry Bozzio
Flint is offline   Reply With Quote
Old 11-21-2010, 09:30 PM   #2
Flint
Snowflake
 
Join Date: Mar 2006
Location: Dystopia
Posts: 13,136
This illustrates my dilemma:

Quote:
Please enter a password: abc
Passwords must be at least 6 characters long
Please enter a password: abcdef
Passwords must include at least on digit (1-9)
Please enter a password: 123
Passwords must be at least 6 characters long
Please enter a password: abcdef
Passwords must include at least on digit (1-9)
Please enter a password: 123
Thank you that is a valid password

Press Enter to close window...
I know how to evaluate for one or the other, but not both. I could repeat my "hack" ad infinitum, but it would always, eventually let you enter 123 and have it accpeted as valid.
__________________
******************
There's a level of facility that everyone needs to accomplish, and from there
it's a matter of deciding for yourself how important ultra-facility is to your
expression. ... I found, like Joseph Campbell said, if you just follow whatever
gives you a little joy or excitement or awe, then you're on the right track.

. . . . . . . . . . . . . . . . . . . . . . . . . . Terry Bozzio
Flint is offline   Reply With Quote
Old 11-21-2010, 11:16 PM   #3
Pete Zicato
Turns out my CRS is a symptom of TMB.
 
Join Date: Jan 2010
Location: Chicago suburbs
Posts: 2,916
What you want to do is to check the minimum number of times.


bool oklength = PassLength(password);
bool okdigit = containDigit(password);

while (!okLength || !okDigit)
{
if (!okLength)
// err MSG

if (!okDigit)
// err MSG

// get password again


oklength = PassLength(password);
okdigit = containDigit(password);

}
__________________


Talk nerdy to me.
Pete Zicato is offline   Reply With Quote
Old 11-22-2010, 10:16 AM   #4
Flint
Snowflake
 
Join Date: Mar 2006
Location: Dystopia
Posts: 13,136
Thank you. I came to more or less the same conclusion.

All last night, I was dreaming in flowcharts. I was continuously, acutely aware that the subject of each dream was being passed as a parameter to the dream function. For a nice dose of recursion, I think the only dream I had was the one in which the above happened.

When I woke up this morning I was thinking this:

Quote:
//bool function (a) checks password length
//bool function (b) checks if password contains digit

get password

while ( ((a) not true) OR ((b) not true) )

{

if ((a) not true)
“Error message”
get password

if ((b) not true)
“Error message”
get password


}

“That is a valid password”
That should work, right?
__________________
******************
There's a level of facility that everyone needs to accomplish, and from there
it's a matter of deciding for yourself how important ultra-facility is to your
expression. ... I found, like Joseph Campbell said, if you just follow whatever
gives you a little joy or excitement or awe, then you're on the right track.

. . . . . . . . . . . . . . . . . . . . . . . . . . Terry Bozzio
Flint is offline   Reply With Quote
Old 11-22-2010, 10:30 AM   #5
Lamplighter
Person who doesn't update the user title
 
Join Date: Jun 2010
Location: Bottom lands of the Missoula floods
Posts: 6,402
Don't you need a way out of the loop if the User wants to "Cancel".
Lamplighter is offline   Reply With Quote
Old 11-22-2010, 11:29 AM   #6
Pete Zicato
Turns out my CRS is a symptom of TMB.
 
Join Date: Jan 2010
Location: Chicago suburbs
Posts: 2,916
Quote:
Originally Posted by Flint View Post
That should work, right?
No. Step through the code and ask yourself what would happen if the password were too short and had no digit.

@Lamplighter - yes in a real world program. Flint didn't mention it as part of the exercise.
__________________


Talk nerdy to me.
Pete Zicato is offline   Reply With Quote
Old 11-22-2010, 02:16 PM   #7
Flint
Snowflake
 
Join Date: Mar 2006
Location: Dystopia
Posts: 13,136
Quote:
Originally Posted by Pete Zicato View Post
No. Step through the code and ask yourself what would happen if the password were too short and had no digit.
I should explain, the condition of the while loop would be written as:

Quote:
while ((!passLength(password)) || (!containDigit(password)))
...so it actually calls both functions, and should execute the loop if either one (or both) is false.

Once inside the loop, it should keep prompting and re-executing the loop until "false OR false" is false.
...

If I step through using "abc" as the input (too short and has no digit), it would say too short and get a new password. Then evaluate for digits. Then evaluate the loop again. Right?
__________________
******************
There's a level of facility that everyone needs to accomplish, and from there
it's a matter of deciding for yourself how important ultra-facility is to your
expression. ... I found, like Joseph Campbell said, if you just follow whatever
gives you a little joy or excitement or awe, then you're on the right track.

. . . . . . . . . . . . . . . . . . . . . . . . . . Terry Bozzio

Last edited by Flint; 11-22-2010 at 02:31 PM.
Flint is offline   Reply With Quote
Old 11-22-2010, 02:47 PM   #8
Happy Monkey
I think this line's mostly filler.
 
Join Date: Jan 2003
Location: DC
Posts: 13,575
I think yours would return a valid password, but [edit]it won't tell them what's wrong if they enter a short password twice in a row it's not as concise as it could be.

Code:
bool passLength(string) // just print error, and return true/false.  Don't read a new pw
bool containDigit(string) // just print error, and return true/false.  Don't read a new pw

string getPW()
{
  string pw = read line;
  while (( ! passlength(pw) ) || ( ! containDigit(pw) ))
  {
    pw = read line;
  }
  return pw;
}
__________________
_________________
|...............| We live in the nick of times.
| Len 17, Wid 3 |
|_______________| [pics]

Last edited by Happy Monkey; 11-22-2010 at 02:55 PM. Reason: logic error
Happy Monkey is offline   Reply With Quote
Old 11-22-2010, 02:56 PM   #9
Flint
Snowflake
 
Join Date: Mar 2006
Location: Dystopia
Posts: 13,136
Oh, I see. Put the error message in the function. Well, yes, they always go together.



Thank you, all. For your help here I will send you a singing telegram from a juggling midget hooker on a unicycle, and/or make a modest donation to the Cellar tip jar. My choice.
__________________
******************
There's a level of facility that everyone needs to accomplish, and from there
it's a matter of deciding for yourself how important ultra-facility is to your
expression. ... I found, like Joseph Campbell said, if you just follow whatever
gives you a little joy or excitement or awe, then you're on the right track.

. . . . . . . . . . . . . . . . . . . . . . . . . . Terry Bozzio
Flint is offline   Reply With Quote
Old 11-22-2010, 08:13 PM   #10
Flint
Snowflake
 
Join Date: Mar 2006
Location: Dystopia
Posts: 13,136
Still haven't got it quite worked out, but I see that what I turned in has been graded and I got a 100. So... no rush, but I'm still going to keep at this until it works exactly right every time, under every circumstance.
__________________
******************
There's a level of facility that everyone needs to accomplish, and from there
it's a matter of deciding for yourself how important ultra-facility is to your
expression. ... I found, like Joseph Campbell said, if you just follow whatever
gives you a little joy or excitement or awe, then you're on the right track.

. . . . . . . . . . . . . . . . . . . . . . . . . . Terry Bozzio
Flint is offline   Reply With Quote
Old 11-23-2010, 12:00 AM   #11
Flint
Snowflake
 
Join Date: Mar 2006
Location: Dystopia
Posts: 13,136
Okay, now THIS version works right, every time, under every condition.

Quote:
#include<iostream>
#include<cstring>
#include<cctype>
using namespace std;

//Function checks the password for length. (a)
bool passLength(char[]);

//Function checks the password for a digit. (b)
bool containDigit(char[]);

int main()
{
const int SIZE = 21;
char password[SIZE];

cout << "Please enter a password: ";
cin.getline(password, SIZE);

while ((!passLength(password)) || (!containDigit(password)))
{
if (!passLength(password))
{
cout << "Passwords must be at least 6 characters long" << endl;
cout << "Please enter a password1: ";
cin.getline(password, SIZE);
(passLength(password)); //(a)
}

if (!containDigit(password))
{
cout << "Passwords must include at least on digit (1-9)" << endl;
cout << "Please enter a password2: ";
cin.getline(password, SIZE);
(containDigit(password)); //(b)
}
}

cout << "Thank you that is a valid password" << endl;


//Keep the window open until Enter key is pressed.
cout << "\nPress Enter to close window..." << endl;
std::cin.get();

return 0;
}

bool passLength(char password[]) //(a)
{
int lengthPass = 6;
int length = strlen(password);

if (lengthPass <= length)
return true;
else return false;
}


bool containDigit(char password[]) //(b)
{
int index = 0;
int length = strlen(password);

for (index = 0; index < length; index++ )
{
if (isdigit(password[index]))
return true;
}
return false;

}
Now, I agree it could be more concise. Since this is the first lesson I had to actually stop and think about, I feel like I want to keep working on it. Keep in mind, I already got a 100 on this. Now, it's just for the principle.
__________________
******************
There's a level of facility that everyone needs to accomplish, and from there
it's a matter of deciding for yourself how important ultra-facility is to your
expression. ... I found, like Joseph Campbell said, if you just follow whatever
gives you a little joy or excitement or awe, then you're on the right track.

. . . . . . . . . . . . . . . . . . . . . . . . . . Terry Bozzio
Flint is offline   Reply With Quote
Old 11-23-2010, 12:18 AM   #12
Flint
Snowflake
 
Join Date: Mar 2006
Location: Dystopia
Posts: 13,136
This is somewhat better, as far as a more streamlined main function...
Quote:
#include<iostream>
#include<cstring>
#include<cctype>
using namespace std;

//Function checks the password for length. (a)
bool passLength(char[]);

//Function checks the password for a digit. (b)
bool containDigit(char[]);

const int SIZE = 21;
char password[SIZE];
Quote:
int main()
{
cout << "Please enter a password: ";
cin.getline(password, SIZE);

while ((!passLength(password)) || (!containDigit(password)))
{
if (!passLength(password))
(passLength(password)); //(a)

if (!containDigit(password))
(containDigit(password)); //(b)
}

cout << "Thank you that is a valid password" << endl;


//Keep the window open until Enter key is pressed.
cout << "\nPress Enter to close window..." << endl;
std::cin.get();

return 0;
}
Quote:
bool passLength(char password[]) //(a)
{
int lengthPass = 6;
int length = strlen(password);

if (lengthPass <= length)
return true;
else
{
cout << "Passwords must be at least 6 characters long" << endl;
cout << "Please enter a password: ";
cin.getline(password, SIZE);
return false;
}
}
Quote:
bool containDigit(char password[]) //(b)
{
int index = 0;
int length = strlen(password);

for (index = 0; index < length; index++ )
{
if (isdigit(password[index]))
return true;
}
cout << "Passwords must include at least on digit (1-9)" << endl;
cout << "Please enter a password: ";
cin.getline(password, SIZE);
return false;
}
__________________
******************
There's a level of facility that everyone needs to accomplish, and from there
it's a matter of deciding for yourself how important ultra-facility is to your
expression. ... I found, like Joseph Campbell said, if you just follow whatever
gives you a little joy or excitement or awe, then you're on the right track.

. . . . . . . . . . . . . . . . . . . . . . . . . . Terry Bozzio
Flint is offline   Reply With Quote
Old 11-23-2010, 10:01 AM   #13
Happy Monkey
I think this line's mostly filler.
 
Join Date: Jan 2003
Location: DC
Posts: 13,575
You are reading new passwords all over the place. What if the password you read in passLength() is good? You return false anyway and ask for a new one at the next step.

You should only do one getline() per loop.
__________________
_________________
|...............| We live in the nick of times.
| Len 17, Wid 3 |
|_______________| [pics]
Happy Monkey is offline   Reply With Quote
Old 11-23-2010, 11:34 AM   #14
Flint
Snowflake
 
Join Date: Mar 2006
Location: Dystopia
Posts: 13,136
Quote:
Originally Posted by HM
You are reading new passwords all over the place.
...
You should only do one getline() per loop.
I understand what you're saying, but the program has to do this:

Quote:
Please enter a password: pass6

Passwords must be at least 6 characters long


Please enter a password: TarrantNW

Passwords must include at least one digit (1-9)


Please enter a password: Tccd03

Thank you that is a valid password
Quote:
Originally Posted by HM
What if the password you read in passLength() is good? You return false anyway and ask for a new one at the next step.
If the password I read in passLength is good (true for both conditions) then it is not false for containDigit. containDigit only runs on the condition of containDigit being false. If it is true, containDigit is not called, and the while condition of the loop exits to main function.
__________________
******************
There's a level of facility that everyone needs to accomplish, and from there
it's a matter of deciding for yourself how important ultra-facility is to your
expression. ... I found, like Joseph Campbell said, if you just follow whatever
gives you a little joy or excitement or awe, then you're on the right track.

. . . . . . . . . . . . . . . . . . . . . . . . . . Terry Bozzio
Flint is offline   Reply With Quote
Old 11-23-2010, 12:21 PM   #15
Happy Monkey
I think this line's mostly filler.
 
Join Date: Jan 2003
Location: DC
Posts: 13,575
I think I was wrong about the bad behavior again; it should work. But it is very complicated. The test functions can return false when the password has been changed to a good one. The structure of the while loop corrects for it, but the behavior of the functions is not what one would expect.

The snippet I posted would give the same behavior, but is much simpler.

This would allow the error reporting to be in the loop, and only calls each test once:
Code:
bool passLength(string) // just return true/false.  Don't read a new pw or print error
bool containDigit(string) // just return true/false.  Don't read a new pw or print error

string getPW()
{
  string password;
  bool ok=false;
  while ( ! ok )
  {
    cout << "Please enter a password: ";
    cin.getline(password, SIZE);

    if (! passlength(password)
    {
      cout << "Passwords must be at least 6 characters long" << endl;
    } 
    else if ( ! containDigit(password) )
    {
      cout << "Passwords must include at least on digit (1-9)" << endl;
    }
    else
    {
      ok=true;
    }
  }
  return password;
}
__________________
_________________
|...............| We live in the nick of times.
| Len 17, Wid 3 |
|_______________| [pics]
Happy Monkey is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

All times are GMT -5. The time now is 02:20 PM.


Powered by: vBulletin Version 3.8.1
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.