2

I have made a email validation program in C#, but how do I check data outside of the string?

Here is my C# code:

private bool CheckEmail()
{
    string email1 = email.Text;

    //calculating the length of the email
    int EmailLen = email1.Length;
    int num = 0;

    //the first character of the email must not be the "@"
    if (email1.Substring(0, 1) != "@")
    {
        //checking the email entered after the first character as it is not a "@" so i will start from 1.
        for (int i = 1; i < EmailLen; i++)
        {
            //prevents there from being two "@"next to each other
            if (email1[i] == '@' && (i + 1) < email1.Length && email1[i + 1] != '@')
            {
                //if there is an "@" in the email then num will increase by one
                num = num + 1;

                //now the stored value of i is the position where the "@" is placed. j will be i+2 as there should be at least one character after the "@"
                int j = i + 2;
                if (j < EmailLen)
                {
                    for (int k = j; k < EmailLen; k++)
                    {
                        //when it finds a "." In the email, the character after the "." Should not be empty or have a space, e.g. it should be something like ".com"

                        if (email1[k] == '.' && k + 1 < email1.Length && email1[k + 1] != ' ')
                        {
                            num = num + 1;
                        }
                    }
                }
                else
                {
                    break;
                }
            }
        }
    }
    else
    {
        num = 0;
    }

    //if the num is 2, then the email is valid, otherwise it is invalid.  If the email had more than one "@" for example, the num will be greater than 2.

    if (num == 2)
    {
        return true;
    }
    else
    {
        return false;
    }
}

When I try typing in “aa@”, I get this error: “Index and length must refer to a location within the string.”

enter image description here

When I ty typing in aa@a. , I get this error: “Index and length must refer to a location within the string.”

enter image description here

Hamoudy
  • 559
  • 2
  • 8
  • 24

2 Answers2

2

You cannot access data outside of the string. This is for a very good reason - doing so would violate the type safety that is a major attraction of a virtual machine like the .NET CLR.

You just want to check your bounds to make sure you're not trying to access a part of the string that doesn't exist. BTW, for checking single characters, you totally want to be doing email1[i], not email1.Substring(i, 1), so you're not constructing new string objects left, right and center.

Your first test should be:

if (email1[i] == '@' && i + 1 < email1.Length && email1[i + 1] != '@')
MattW
  • 4,480
  • 1
  • 12
  • 11
  • that worked for the first test, how would you convert this line: email1.Substring(k, 1) == "." && email1.Substring(k + 1, 1) != "" && email1.Substring(k + 1, 1) != " " – Hamoudy Mar 25 '13 at 20:55
  • Again put the length check before you start trying to dereference k+1: `(email1[k] == '.' && k + 1 < email1.Length && Email1[k + 1] != ' ')`; the test for empty string was presumably trying to do what the length check does. – MattW Mar 25 '13 at 20:59
  • i think this is now a foolproof method for checking emails, do you have any exceptions – Hamoudy Mar 25 '13 at 21:04
  • Won't this allow `a@@b.c`? On the first `@`, your first if condition will not be met, but it will on the second. Also, it's technically valid for people to have stupid email addresses like `"a@b"@example.com` although I wouldn't want to trust that all the MTAs and MUAs in the wild that might have to deal with such an address would do so correctly. The RFC which defines mail addresses is much more complex than you've allowed for, it's a genuine nightmare trying to write a correct mail address validator. – MattW Mar 25 '13 at 21:11
  • 1
    I might rephrase the second sentence: the reason is that there is no data outside of the string, so far as you and the string are concerned. While there could be memory after it, the contents thereof are none of your business when viewed through the string. In reality, there's a good chance the memory after the string's buffer isn't even yours and attempting to access it would crash your program. – ssube Mar 25 '13 at 21:11
  • 2
    @Hamoudy: The code you give here does not even come close to validating that a string contains a good email address. To pick just one off the top of my head, `abc"def"ghi@jkl.com` is not a valid email address, but your program allows it. – Eric Lippert Mar 25 '13 at 21:19
  • Also it looks like you'll throw out `a@subdomain.example.com` even though it's perfectly valid. This would cause huge problems emailing to, for example, the UK where many people have addresses of the form `person@company.co.uk` – MattW Mar 25 '13 at 21:20
  • @EricLippert yes I know now, mat also pointed that out as well, but thanks for informing me – Hamoudy Mar 25 '13 at 21:21
  • 2
    @Hamoudy: Before you write any more code you should read the relevant documentation. A good place to start is http://tools.ietf.org/html/rfc3696 – Eric Lippert Mar 25 '13 at 21:24
  • 1
    thanks a lot for your advice, and MattW you have a lot of good points there! – Hamoudy Mar 25 '13 at 21:26
1

Your problem is

email1.Substring(i + 1, 1)

On the last iteration of the for loop, i == EmailLen -1.

So i + 1 == EmailLen, which is one past the end of the string.

mbeckish
  • 10,485
  • 5
  • 30
  • 55