First, heed what Jeroen Vannevel said; it will save you much grief.
Of all the assumptions you've made here, only one is correct: there
has to be an @
in the email address. Otherwise: it can have multiple
dots, it can have no dots, it can have no TLD, it can have no domain,
it can have IP addresses as domain, it can have quotes, it can have
spaces, etc. When validating emails the correct approach is to check
for the presence of an @
and hope for the best. You can always try to
send an email and see if it bounces back.
I'll address the code as-is, even if the purpose of it is not necessarily a workable idea. It's a good exercise in working with Strings.
Variable naming
Let's start here...
String email="";
int at1=0,at2=0;
int dot1=0;
boolean at = false, dot=false, domain=false, tld=false;
Your variables say the name of the character(s) it is checking, but not what it is checking for. Most IDEs have a Refactor/Rename tool so let's use that for your code. This will make their intent more clear.
Also, in the case of your script, most if not all the variables get overwritten at some point or another. So either overwrite only if needed, or don't assign a value until you know what value it should hold. I will use the former.
String email;
int atCount = 0;
int atPosition = 0;
int dotPosition = 0;
boolean hasAt = false, hasDot = false, hasDomain = false, hasTLD = false;
String errors = "Invalid email address: ";
int errorCount = 0;
I added a few more variables, as you can see; we'll use those for aggregating errors.
Checking for @
You're looping twice over the same email address looking for the same character. Why not just save yourself one loop and do all your assignments in one pass? Also, please use curly braces even for one-liners, it will make your code easier to follow. It's also good to use white space around operators.
// Checking for '@' char
for (int i = 0; i < email.length(); i++) {
if (email.charAt(i) == '@') {
atCount++;
if (atCount == 1) {
atPosition = i;
}
}
}
if (atCount != 1) {
//hasAt = false; // no need for this; already false
errors += "Email must have exactly 1 '@' character. ";
errorCount++;
} else {
hasAt = true;
}
// atCount =0; // no need for this; we're not using it anywhere else
Checking for other things
We can use some similar techniques to clean-up the rest of the code. Note the use of errors
to add any applicable errors, and errorCount
to keep track.
// Checking the domain is not empty
if ((atPosition + 1) < email.length()) {
if (email.charAt(atPosition + 1) == '.') {
// hasDomain = false; // no need; already false
errors += "Email does not have a domain or domain is empty. ";
errorCount++;
} else {
hasDomain = true;
}
}
//Checking if there is at least one dot after the '@' char
for (int i = atPosition; i < email.length(); i++) {
if (email.charAt(i) == '.') {
hasDot = true;
}
}
if (hasDot != true) {
errors += "Must have at least one dot after '@' character. ";
errorCount++;
}
// no else; hasDot would already be false
//Getting last dot's position
for (int i = 0; i < email.length(); i++) {
if (email.charAt(i) == '.') {
dotPosition = i;
}
}
//Checking there's some Top-Level Domain
if (email.length() == dotPosition + 1) {
// hasTLD = false; // no need; already false
errors += "No top-level domain found. ";
errorCount++;
} else {
hasTLD = true;
}
do {...} while (...)
This construct is not working out too good for this purpose. The primary issue with it is that if any error is found during it, it just starts over from the start. It never does anything useful if there is an error, like print the error or exit the program.
Perhaps instead we can just move the logic into a method of its own, and call that method in main()
against the input email address?
public class MailTest {
public static void main (String [] args){
String email = JOptionPane.showInputDialog("Insert your email");
isValidEmail(email);
}
static boolean isValidEmail(String inputEmail) {
/* All your vars and logic in here */
}
}
And we can use a similar logic at the end in a simple if() ... else
statement, and return whether or not the email is valid (according to your criteria).
if (hasAt && hasDomain && hasDot && hasTLD) {
System.out.println("Email entered: " + email);
errors = "No errors found.";
System.out.println(errors);
return true;
} else {
System.out.println("Email entered: " + email);
System.out.println("Errors found: " + errorCount);
System.out.println(errors);
return false;
}
So you get a useful output, and a useful return value...
Email entered: hello.world.com
Errors found: 1
Invalid email address: Email must have exactly 1 '@' character.
Email entered: [email protected]
No errors found.
Everything put together:
import javax.swing.JOptionPane;
public class MailTest {
public static void main (String [] args){
String email = JOptionPane.showInputDialog("Insert your email");
isValidEmail(email);
}
static boolean isValidEmail(String inputEmail) {
String email = inputEmail;
int atCount = 0;
int atPosition = 0;
int dotPosition = 0;
boolean hasAt = false, hasDot = false, hasDomain = false, hasTLD = false;
String errors = "Invalid email address: ";
int errorCount = 0;
// Checking for '@' char
for (int i = 0; i < email.length(); i++) {
if (email.charAt(i) == '@') {
atCount++;
if (atCount == 1) {
atPosition = i;
}
}
}
if (atCount != 1) {
errors += "Email must have exactly 1 '@' character. ";
errorCount++;
} else {
hasAt = true;
}
// Checking the domain is not empty
if ((atPosition + 1) < email.length()) {
if (email.charAt(atPosition + 1) == '.') {
errors += "Email does not have a domain or domain is empty. ";
errorCount++;
} else {
hasDomain = true;
}
}
//Checking if there is at least one dot after the '@' char
for (int i = atPosition; i < email.length(); i++) {
if (email.charAt(i) == '.') {
hasDot = true;
}
}
if (hasDot != true) {
errors += "Must have at least one dot after '@' character. ";
errorCount++;
}
//Getting last dot's position
for (int i = 0; i < email.length(); i++) {
if (email.charAt(i) == '.') {
dotPosition = i;
}
}
//Checking there's some Top-Level Domain
if (email.length() == dotPosition + 1) {
errors += "No top-level domain found. ";
errorCount++;
} else {
hasTLD = true;
}
// validity returning routine
if (hasAt && hasDomain && hasDot && hasTLD) {
System.out.println("Email entered: " + email);
errors = "No errors found.";
System.out.println(errors);
return true;
} else {
System.out.println("Email entered: " + email);
System.out.println("Errors found: " + errorCount);
System.out.println(errors);
return false;
}
}
}
@
in the email address. Otherwise: it can have multiple dots, it can have no dots, it can have no TLD, it can have no domain, it can have IP addresses as domain, it can have quotes, it can have spaces, etc. When validating emails the correct approach is to check for the presence of an@
and hope for the best. You can always try to send an email and see if it bounces back. \$\endgroup\$EmailAddressAttribute
directly, but Microsoft has a very nice Regular Expression you can look at here: referencesource.microsoft.com/… \$\endgroup\$