1
\$\begingroup\$

I'm very new to programming and coding and "wrote" my first program from scratch as an at home exercise after doing some online courses.

My question is not necessarily a problem I'm having with the program, but I suppose more so just insight to simplify my code. I could not really find anything anywhere for my question or maybe, I just didn't understand the answers I read.

I made a simple username and password checker that has restrictions. Username must not be greater than 8 characters and cannot have a special character. Password must not be greater than 8 characters, cannot have a special character, must have one upper, and have one lower case letter.

the program prompts the user if there are any errors in the making of their username or password. And will keep prompting until everything checks out. Once it passes, it will give an end prompt and close

Everything is working fine, not perfect but better than 'broken'.

But I can't shake the feeling that my loops can be way more simple than this...Is there something I'm missing that can cut this down more?

I also notice that if the user enters in the values, and it skips an error check, if they reentered the value and it is supposed to prompt and error check that is before the current error check they are on, it won't loop back to that specific check.

For example, user enters password, 'minimum number' is there, but 'length' is bad, it will enter the 'length' while loop, but if the user enters in the right length, and forgets a number, it will just loop all the way to the beginning and not back to the 'minimum number' while loop. I know this happens, but cannot for the life of me think of any other way to make that work and have it more optimized with a different loop structure!

Any ideas?

I tried a switch statement but that didn't seem to make it any better, and didn't even work for me. I could make a method out of the while loops but does that necessarily make the code "simplified"? If it's all there anyway, just not in main()?

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;

 namespace UsernamePasswordBasicProgram
 {


class Program
{
    static void Main(string[] args)

    {
        char[] invalid = { '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '{', '}', ' ', '[', ']', ',', '.', '?', '/', '|', '_', '-', '+', '=' };
        char[] upper = { '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' };
        char[] lower = { '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' };
        char[] num = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        int maxLength = 8;
        int userLength;
        int passLength;
        int minUpper = -1;
        int minLower = -1;
        int minNum = -1;
        int invFound = -1;
        int passMinUpper = -1;
        int passMinLower = -1;
        int passMinNum = -1;
        int passInvFound = -1;
        string userName;
        string password;

        Console.WriteLine("This program will ask for a username and then a password");
        Console.WriteLine("Username and password cannot contain any spaces or special characters");
        Console.WriteLine("The password must contain at least one uppercase and lowercase letter, and at least one number");
        Console.WriteLine("*************************************************************************************************");

        Console.WriteLine("Please enter a username: ");
        userName = Console.ReadLine();
        userLength = userName.Length; // stores length of username to compare to max length.
        invFound = userName.IndexOfAny(invalid); // changes number of int if an invalid char is found.
        minUpper = userName.IndexOfAny(upper);// changes number if upper is found
        minLower = userName.IndexOfAny(lower);// changes number if lower is found
        minNum = userName.IndexOfAny(num);// changes number if a number is found


        if (userLength > 8 || invFound != -1)
        {
            do
            {
                Console.WriteLine("Error found...");
                Console.WriteLine("Please re-enter username: ");
                userName = Console.ReadLine();
                userLength = userName.Length; 
                invFound = userName.IndexOfAny(invalid); 
                minUpper = userName.IndexOfAny(upper);
                minLower = userName.IndexOfAny(lower);
                minNum = userName.IndexOfAny(num);


                while (userLength > 8)
                {
                    Console.WriteLine("Username too long. Please re-enter: ");
                    userName = Console.ReadLine();
                    userLength = userName.Length;
                    invFound = userName.IndexOfAny(invalid);
                    minUpper = userName.IndexOfAny(upper);
                    minLower = userName.IndexOfAny(lower);
                    minNum = userName.IndexOfAny(num);
                }
                while (invFound != -1)
                {
                    Console.WriteLine("Invalid character found, please re-enter: ");
                    userName = Console.ReadLine();
                    userLength = userName.Length; 
                    invFound = userName.IndexOfAny(invalid); 
                    minUpper = userName.IndexOfAny(upper);
                    minLower = userName.IndexOfAny(lower);
                    minNum = userName.IndexOfAny(num);
                }

            } while (userLength > 8 || invFound != -1);
        }


        Console.WriteLine("************************");
        Console.WriteLine("Please enter in a password");
        password = Console.ReadLine();
        passLength = password.Length;
        passInvFound = password.IndexOfAny(invalid);
        passMinUpper = password.IndexOfAny(upper);
        passMinLower = password.IndexOfAny(lower);
        passMinNum = password.IndexOfAny(num);

        

        if (passMinUpper == -1 || passMinLower == -1 || passMinNum == -1 || passLength > 8 || passInvFound != -1)
        {
            do
            {
                Console.WriteLine("Error found...");
                Console.WriteLine("Please re-enter password: ");
                password = Console.ReadLine();
                passLength = password.Length;
                passInvFound = password.IndexOfAny(invalid);
                passMinUpper = password.IndexOfAny(upper);
                passMinLower = password.IndexOfAny(lower);
                passMinNum = password.IndexOfAny(num);

                while (passMinUpper == -1 || passMinLower == -1)
                {
                    Console.WriteLine("Missing Upper or Lowercase, please re-enter : ");
                    password = Console.ReadLine();
                    passLength = password.Length;
                    passInvFound = password.IndexOfAny(invalid);
                    passMinUpper = password.IndexOfAny(upper);
                    passMinLower = password.IndexOfAny(lower);
                    passMinNum = password.IndexOfAny(num);
                }

                while (passMinNum == -1)
                {
                    Console.WriteLine("Missing a number, please re-enter: ");
                    password = Console.ReadLine();
                    passLength = password.Length;
                    passInvFound = password.IndexOfAny(invalid);
                    passMinUpper = password.IndexOfAny(upper);
                    passMinLower = password.IndexOfAny(lower);
                    passMinNum = password.IndexOfAny(num);
                    
                }

                while (passLength > 8)
                {
                    Console.WriteLine("Username too long. Please re-enter: ");
                    password = Console.ReadLine();
                    passLength = password.Length;
                    passInvFound = password.IndexOfAny(invalid);
                    passMinUpper = password.IndexOfAny(upper);
                    passMinLower = password.IndexOfAny(lower);
                    passMinNum = password.IndexOfAny(num);
                }
                while (passInvFound != -1)
                {
                    Console.WriteLine("Invalid character found, please re-enter: ");
                    password = Console.ReadLine();
                    passLength = password.Length;
                    passInvFound = password.IndexOfAny(invalid);
                    passMinUpper = password.IndexOfAny(upper);
                    passMinLower = password.IndexOfAny(lower);
                    passMinNum = password.IndexOfAny(num);
                }

            } while (passMinUpper == -1 || passMinLower == -1 || passMinNum == -1 || passLength > 8 || passInvFound != -1);
        }
        Console.WriteLine("**********************************");
        Console.WriteLine("Your Credentials have been saved");
        Console.ReadLine();

    }
    }
    }       

   /* User will enter a username and password, username or password cannot contain 
   special characters or spaces.
   * the password must have at least one uppercase letter and one lowercase letter.

   the program will prompt the user if any of the given is invalid.
   the program will prompt the user if it is successful, and then will display what the 
   user entered.
   the program will then ask if the user wants to enter in another set or exit. */
\$\endgroup\$
1
  • \$\begingroup\$ userLength > 8 = (if user length is greater than 8), you're just using the opposite condition here. It should be userLength < 8 (while user length is less than 8). invFound != -1 (while there is no invalid characters) the correct one should be invFound > 0. as IndexOf and IndexOfAny would return -1 if there is no match. recheck your other conditions as well. \$\endgroup\$
    – iSR5
    Commented Aug 13, 2023 at 0:38

1 Answer 1

2
\$\begingroup\$

Long story short, use LINQ and defensive programming (i.e. jump statements):

By doing so, you greatly reduce the code and it becomes much easier to deal with.

The code:

char[] invalid = { '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '{', '}', ' ', '[', ']', ',', '.', '?', '/', '|', '_', '-', '+', '=' };

while (true)
{
    Console.WriteLine("Type your user name then press Enter key.");

    var line = Console.ReadLine();

    if (string.IsNullOrEmpty(line))
    {
        Console.WriteLine("User name cannot be empty.");
        continue;
    }

    if (line.Length < 3)
    {
        Console.WriteLine("User name must be at least 3 characters long.");
        continue;
    }

    if (line.Any(s => invalid.Contains(s)))
    {
        Console.WriteLine($"User name cannot contain the following characters: {string.Join(", ", invalid.Select(s => $"'{s}'"))}.");
        continue;
    }

    if (!line.Any(char.IsAsciiLetterLower))
    {
        Console.WriteLine("User name must contain at least one lower case character.");
        continue;
    }

    if (!line.Any(char.IsAsciiLetterUpper))
    {
        Console.WriteLine("User name must contain at least one upper case character.");
        continue;
    }

    if (!line.Any(char.IsDigit))
    {
        Console.WriteLine("User name must contain at least one digit character.");
        continue;
    }

    Console.WriteLine("User name is valid.");
    break;
}

The output:

Type your user name then press Enter key.

User name cannot be empty.
Type your user name then press Enter key.

User name must be at least 3 characters long.
Type your user name then press Enter key.
a
User name must be at least 3 characters long.
Type your user name then press Enter key.
ab
User name must be at least 3 characters long.
Type your user name then press Enter key.
abc
User name must contain at least one upper case character.
Type your user name then press Enter key.
abC
User name must contain at least one digit character.
Type your user name then press Enter key.
aB1!
User name cannot contain the following characters: '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '{', '}', ' ', '[', ']', ',', '.', '?', '/', '|', '_', '-', '+', '='.
Type your user name then press Enter key.
aB1
User name is valid.

Adjust as you see fit.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.