-1

I want the user to only be able to proceed if their username's last 3 characters are digits. How would you code that? Any help would be appreciated!

My current code but it doesn't work:

static bool checkUsername(string user)
        {
            //bool containsAtLeastThreeDigits = user.Any(char.IsDigit);
            var counter = user.Count(x => Char.IsDigit(x));
            bool valid = false;
            int count = 0;

            if (counter == 3)
            {
                count++;
            }
            else
            {
                Console.WriteLine("Password must have 3 digits");
            }

            if (count == 1)
            {
                valid = true;
            }
            return valid;
        }
corzan
  • 21
  • 4
  • 1
    Please post any attempt you have made. Here's a few hints to get you going. You want to get the last 3 characters of the `string` username (https://stackoverflow.com/questions/6413572/how-do-i-get-the-last-four-characters-from-a-string-in-c/6413598) then check to see if these characters are a number (https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryparse?view=netcore-3.1), you will also need to check to make sure that the username is at least 3 characters in length. – Ryan Wilson Sep 30 '20 at 20:36
  • 1
    Sorry, added my code now – corzan Sep 30 '20 at 20:40
  • First I'd check to make sure the username is greater than or equal to 3 characters, else it's not going to pass the test, then if greater than or equal to 3 characters in length, get the last 3 characters of the username using `.SubString()`, then use `Int32.TryParse` to check if the last 3 characters make a number. I linked to articles covering `SubString()` and `TryParse()` above. If you still need help, let me know. – Ryan Wilson Sep 30 '20 at 20:43
  • 2
    Your question states that you want the last 3 characters to be integers. But from your code sample, it looks like you were trying to just make sure that *any* three were integers. – Casey Crookston Sep 30 '20 at 20:52

5 Answers5

1

You can simply check if the Length is greater than 2 characters, and then check that the substring consisting of the last 3 characters are all digits:

public static bool Last3AreDigits(string input)
{
    return input?.Length > 2 && input.Substring(input.Length - 3).All(char.IsDigit);
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43
1

Edit: I've just seen Casey Crookston's comment about the ambiguity of your question. So, if you do want to check to see if the input has at least 3 digits in any position, you can use the following:

using System.Linq;

static bool checkUsername(string user)
{
    return user?.Count(char.IsDigit) >= 3;
}

Original answer (checking the last 3 characters are digits)

You could do this in a couple of ways that are simpler than what you're currently doing.

using System.Linq;

static bool checkUsername(string user)
{
    return user?.Length >= 3 && user.TakeLast(3).All(char.IsDigit);
}

or

using System.Text.RegularExpressions;

static bool checkUsername(string user)
{
    return user != null && Regex.Match(user, @"\d{3}$").Success;
}

\d denotes a digit, the {3} specifies 3 occurrences of the preceding expression (i.e. 3 digits), and $ means match at the end of the string.

John H
  • 14,422
  • 4
  • 41
  • 74
1

Easiest option is to verify the length greater than some min and then use the new C# range indexing. I'm sure there's probably other validation you would want to do. But just the requirements you stated would look like this:

    static readonly (string,bool)[] UsernamesTestData = new (string,bool)[]
        {
            ("good123",true),
            ("bad12",false),
            ("bad1",false),
            ("no",false),
            (" ",false),
            ("",false),
            (null,false),
        };

    static void Main(string[] _)
    {
        foreach (var (username, expected) in UsernamesTestData)
        {
            bool isValid = IsValidUsername(username);

            Console.WriteLine($"{username}: expected: {expected} tested as: {isValid}");
        }
    }

    static bool IsValidUsername(string name)
    {
        if (string.IsNullOrWhiteSpace(name) || name.Length < 4)
            return false;

        return char.IsDigit(name[^1]) && char.IsDigit(name[^2]) && char.IsDigit(name[^3]);
    }
MikeJ
  • 1,299
  • 7
  • 10
0

Since everyone else is using Linq and/or Regex, here's a solution using SubString and TryParse and IndexOfAny:

//1. Checks for Length of at least 3 characters
//2. Tries parsing to a number
//3. Check to make sure a successful parse is a number and doesn't contain {, . + -}. 
//Don't want false positives of things like +10 or -99 etc.
public static bool CheckUsername(string user)
{
    return user?.Length >= 3 && 
           Int32.TryParse(user.Substring(user.Length - 3), out _) && 
           user.Substring(user.Length - 3).IndexOfAny(new char[] { ',', '+', '-', '.' }) == -1;
}
Ryan Wilson
  • 10,223
  • 2
  • 21
  • 40
  • @MikeJ True. DIdn't think about the negative posibility. – Ryan Wilson Sep 30 '20 at 20:59
  • Sorry missed that - didn't see it scrolled off to the right. Now I see your point, and yeah seems reasonable. Seems like more work than just checking the string however user[^1] gives you the last digit for example. – MikeJ Sep 30 '20 at 21:14
  • 1
    @MikeJ No worries. You made a good point. And your answer may be better. This is just another possibility. – Ryan Wilson Sep 30 '20 at 21:15
  • Using tryparse and the value was cool, will clean up the other comments. – MikeJ Sep 30 '20 at 21:20
  • @MikeJ I updated my answer. `001` failed the test. So I checked for `{, . - +}` – Ryan Wilson Sep 30 '20 at 21:29
  • Good point about the leading zeros, something else I didn't think of. I think you're right, and I think I'm back to thinking I was right, you should just check the 3 digits and not use TryParse. – MikeJ Sep 30 '20 at 21:30
  • 1
    @MikeJ Probably. :P But it's different than other proposed solutions, so I think I'll leave it. – Ryan Wilson Sep 30 '20 at 21:31
0

There's also the old-school method for doing this: Check the length, then check the last three characters using a loop:

public static bool Last3AreDigits(string name)
{
    if (name == null || name.Length < 3) return false;

    for (int i = name.Length - 1; i > name.Length - 4; i--)
    {
        if (!char.IsDigit(name[i])) return false;
    }

    return true;
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43