I am working on a password project for school, and I am stumped on one part. I know how to test if a string (or file) contains a digit, or a letter, but in this case we have to verify that there is at least one character that is not a letter. Any clue to how I could do this?

Look at first character. If it's not a letter, then there is at least one character that is not a letter. Stop now. If it is a letter, move on to next character.

Next character: Look at it. If it's not a letter, then there is at least one character that is not a letter. Stop now. If it is a letter, move on to next letter.

Repeat that step over and over until you find something that's not a letter, or get to the end.

That's what I've been trying to do, using cin.get(next), but somehow it's not testing correctly. I will play with it some more...and thanks.

Get all characters first into a single string, then examine them.

Yeah...it's not that. I don't know what I am doing wrong, and I am ready to throw in the towel.

string input;
cin >> input;
for (int i=0; i< input.length(); i++)
{
  if (!isalpha(input[i]))
  {
     // this is NOT a letter. Do something
  }
}

Mine is very similar, but I am getting weird results. The first time a password (incorrect OR correct) is entered, it is proclaimed not to have any non-alphabetic characters. The second time the same password is entered (again, incorrect or correct), it is accepted. It has to be a mistake in my looping somehow, but I am too brain dead to find it.

Want to post the code you have?

string CheckPassword()
{  
    unsigned int index = 0;
    cout << "Enter your password: ";
    getline(cin, password);

    do
    {
        if (password.length() < 5)
        {
            cout << "Your password is too short.  Please re-enter: ";
            getline(cin, password);
        }
        for (unsigned int i = 0; i < password.length(); i++)
        {
            if (isspace(password[i]))
            {
                do
                {
                    cout << "No spaces allowed.  Try again: ";
                    getline(cin, password);
                }while(isspace(password[i]));
            }
        }
        for (index = 0; index < password.length(); index++)
        {
            if(isalpha(password[index])) 
            {
                if(index = password.length())
                {
                    cout << "Password must contain non-alphabetic characters.\n"
                         << "Try again: ";
                    getline(cin, password);
                }
            }
        }
    }while (password.length() < 5);
    return password;
}

That last part of the code is the part giving me an issue...but I had had only about three hours of sleep in almost 48 hours when I wrote it, so don't judge me too harshly...

for (index = 0; index < password.length(); index++) For all letters in the password
if(isalpha(password[index])) if any letter IS alphanumeric
if(index = password.length() set the value of index to length (so that we stop looping?), but why do it in an if construct? This is just misleading and asking for trouble - there are better ways to stop looping
cout << "Password must contain non-alphabetic characters.\n" and then tell the user that the password musn't contain non-alpha characters

You've simply got the logic wrong. You're searching for the first alphanumeric character, and when you find it, you're telling the user they must have non-alphanumeric characters. Makes no sense.

Also, your logic seems wrong in other places. Your check for spaces; what happens if, say the third caracter is a space? You code finds that, and makes the user enter a new password. The user enters a new password in which the second character is a space. Your loop carries on checking at the third character, so never sees that the second character is a space, so allows the password with a space in it.

Simplify your code. Much, much simpler. Really simple.

The following code is simple. Get password, examine every character, check at end to see if there was a "bad" character.

string password;
int passwordIsBad;
int passwordContainsAtLeastOneNonAlphabeticChar;
do{
  passwordContainsAtLeastOneNonAlphabeticChar = 0;
  passwordIsBad = 0; // assume it's fine at start - any one bad thing changes this
  getline(cin, password);


  // length test
  if (password.length() < 5) 
  {
    cout << "Too short.";
    passwordIsBad=1;
  }

  for (int i=0; i<password.length(); i++)
  {
     // each test runs separately on every character

     // is there a nonalpha character?
     if (!isalpha(password[i]))
     {
       passwordContainsAtLeastOneNonAlphabeticChar = 1;
     }

     // is there a space?
     if (isspace(password[i]))
     {
       cout << "No spaces.";
       passwordIsBad=1;
     }

     // other tests here

   }
while (passwordIsBad || !passwordContainsAtLeastOneNonAlphabeticChar) 
  // keep going as long as password is bad OR it doesn't have a non-alpha

I figured out the first part (I am pointedly not looking at your solution yet)...

I used a nested loop, and have tested it rigorously. Thanks for pointing out the errors the first code was causing...it's funny; sometimes you think you think you have tested enough when you really haven't. I think I have the second portion worked out, but I need to type it up in a test program. I will get back to you...

And I do appreciate the help above; it's just that I want to try and figure it out on my own now that I've had some sleep...

string CheckPassword()

    cout << "Enter your password: ";
    getline(cin, password);

    do
    {
        if (password.length() < 5)
        {
            cout << "Your password is too short.  Please re-enter: ";
            getline(cin, password);

            for (unsigned int i = 0; i < password.length(); i++)
            {
                if (isspace(password[i]))
                {
                    do
                    {
                        cout << "No spaces allowed.  Try again: ";
                        getline(cin, password);
                        i = 0;                              
                    }while(isspace(password[i]));
                }
            }
        }
    }while(password.length() < 5);
    return password;
}

This fixes the problem by setting i back to zero. This fix, whilst not incorrect, has fixed the problem by making your code more complicated rather than less.

What happens when you add another test? If the password has no spaces, and you move on to the next test, and then that test requires the user to enter a new password for some reason, how do you go back to repeat the space test?

I think you'd do well to stop coding and just think for a while; come up with the simplest method possible. Dont worry about speed or efficiencny until you have to.

Well, I have until Wednesday night...and I work full time M-F...

Your code is nice, but it doesn't work if you enter a valid password in the first time. I was having that problem with my code too...

it doesn't work if you enter a valid password in the first time

Works fine for me. Here is my code above, wrapped in a main function. Here's a sample session:

j@j-desktop:~/badCode$ ./a.out
errrrr5
pw is errrrr5

Worked fine. Took the password errrr5 on the first go.

#include <string>
#include <iostream>

using namespace std;

int main()
{


string password;
int passwordIsBad;
int passwordContainsAtLeastOneNonAlphabeticChar;
do{
  passwordContainsAtLeastOneNonAlphabeticChar = 0;
  passwordIsBad = 0; // assume it's fine at start - any one bad thing changes this
  getline(cin, password);
  // length test
  if (password.length() < 5) 
  {
    cout << "Too short.";
    passwordIsBad=1;
  }
  for (int i=0; i<password.length(); i++)
  {
     // each test runs separately on every character
     // is there a nonalpha character?
     if (!isalpha(password[i]))
     {
       passwordContainsAtLeastOneNonAlphabeticChar = 1;
     }
     // is there a space?
     if (isspace(password[i]))
     {
       cout << "No spaces.";
       passwordIsBad=1;
     }
     // other tests here
  }
}while (passwordIsBad || !passwordContainsAtLeastOneNonAlphabeticChar); 
  // keep going as long as password is bad OR it doesn't have a non-alpha

  cout << "pw is " << password;
 }

ok... i have come up with a solution to your problem.
Here in this code it allow the user to enter their password
the password entered must have an alphanumeric character and no spaces allowed

    string password; // stores the password the user enters
    bool pwdNotAlpha; // stores true if one alphanumeric is found
    bool pwdspace; // stores false if no space are found

    // runs a do....while loop until a successful password is entered
    do
    {
        // assuming the password is successful at the begining;
        pwdNotAlpha = false;
        pwdspace = true;
        //prompt user for password
        cout<<"Enter your password: ";
        getline(cin, password);

        if(password.length() < 5)
        {
            cout<<"Your password length must be atleast 5 characters!"<<endl;
            continue; // it will skip the rest of the code and go the begin of the do..while loop
        }

        // checking for spaces
        for(unsigned int i = 0; i < password.length(); i++)
        {
            if(isspace(password[i]))
            {
                cout<<"No space are allowed!"<<endl;
                pwdspace = false;
                break; // end for loop
            }
        }

        // checking for non-alpahnumeric character
        for(unsigned int j = 0; j < password.length(); j++)
        {
            if(!isalpha(password[j]))
            {
                pwdNotAlpha = true; 
                break; // end for loop
            }
        }

        cout<<pwdNotAlpha<<" "<<pwdspace<<endl;
    }while(!pwdNotAlpha || !pwdspace);

Mine had to call a function, and there were a few other requirements. I'll send it if you want to see it...

Can one write a || b || c?

Can one write a || b || c?

Yes. In this case:

(a || b || c) will be true if any of a, b, c are true (or non-zero).

Okay...having another stupid moment, lol! And of course there's nothing on this in my text. All finished...hooray!

lol... Glad i kud help you out!!!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.