Email validation in C++

丶灬走出姿态 提交于 2019-12-01 05:53:41

Why not use regex?

#include <iostream>
#include <string>
#include <regex>

bool is_email_valid(const std::string& email)
{
   // define a regular expression
   const std::regex pattern
      ("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");

   // try to match the string with the regular expression
   return std::regex_match(email, pattern);
}

int main()
{
    std::string email1 = "text.example@randomcom";

    std::cout << email1 << " : " << (is_email_valid(email1) ?
      "valid" : "invalid") << std::endl;
}

http://en.cppreference.com/w/cpp/regex

The main problem here is that this is supposed to be a C++ program, but, instead, it became a C program. strstr() and strlen() are C library functions.

In modern C++ we use std::string, iterators, and algorithms, which make the whole task much shorter, and easier to grok. And there's no need to worry about buffer overflows, either:

#include <string>
#include <algorithm>

// Your main() declaration here, etc...

std::string input;

std::cout << "Enter your email address" << std::endl;
std::getline(std::cin, input);

auto b=input.begin(), e=input.end();

if (  (b=std::find(b, e, '@')) != e &&
      std::find(b, e, '.') != e )
{
    std::cout << "Email accepted" << std::endl;
}
else
{
    std::cout << "Email rejected" << std::endl;
}

Now, isn't that shorter, and easier to parse?

Use std::string, not that nasty fixed-size C string stuff.

int main()
{
    string input;
    cout << "Enter your email address\n";
    getline(cin, input);

    size_t at = input.find('@');
    if (at == string::npos)
    {
        cout << "Missing @ symbol\n";
        return 1;
    }

    size_t dot = input.find('.', at + 1);
    if (dot == string::npos)
    {
        cout << "Missing . symbol after @\n";
        return 2;
    }

    cout << "Email accepted.\n";
    return 0;
}
static bool IsEmailAddress(const std::string& str)
{
    // Locate '@'
    auto at = std::find(str.begin(), str.end(), '@');
    // Locate '.' after '@'
    auto dot = std::find(at, str.end(), '.');
    // make sure both characters are present
    return (at != str.end()) && (dot != str.end());
}

You have very restricted and specific rules about valid email addresses that are not reflective of real email addresses. Assuming that's intentional, the main problem I see is you are writing loops when you do not need to. The library function strstr() does the looping for you. You just pass it the string and it will loop through it looking for the char.

So, letting the function do the finding for you, you can divide and conquer the problem like this:

bool is_valid(char const* email)
{
    auto at_pos = std::strchr(email, '@');

    if(at_pos == nullptr)
        return false; // did not find an '@' (rule A violation)

    auto dot_pos = std::strchr(email, '.');

    if(dot_pos == nullptr)
        return false; // did not find an '.' (rule B violation)

    if(dot_pos < at_pos)
        return false; // '.' found before '@' (rule B violation)

    return true; // all rules followed!
}
coder_doe

Try using the below method.

bool ValidateEmail(string email)
{
    if (regex_match(email, regex("([a-z]+)([_.a-z0-9]*)([a-z0-9]+)(@)([a-z]+)([.a-z]+)([a-z]+)"))) 
        return true;

    return false;
}
//Program to validate email

#include<iostream>                 //header files
#include<string>

using namespace std;

int strLength(char str[]);

int email_check(char str[])
{                                               //function to check the conditions for email
int size,pos=0,pos1=0,c=0;
size=strLength(str);
if((str[0]>='a'&& str[0]<='z')||(str[0]>='A'&& str[0]<='Z'))  //first char should be an alphabet
{
for(int i=0;i<size;i++)
{
if((str[i]>='a'&& str[i]<='z')||(str[i]>='0' && str[i]<='9') || str[i]=='.'||str[i]=='_'||str[i]=='-'||str[i]=='#'||str[i]=='@')                                         //combination of characters allowed
{
if(str[i]=='.'||str[i]=='_'||str[i]=='-'||str[i]=='#'||str[i]=='@')    // symbol encountered 
{
if((str[i+1]>='a'&&str[i+1]<='z')||(str[i+1]>='0' &&str[i+1]<='9')) //no 2 repeated symbols
{
if(str[i]=='@')                       //@ encountered, so domain part begins
pos=i;                                  //pos is the position where domain begins
}
else
return 0;
}
}
else
return 0;
}
}
else
return 0;
if(pos==0)
return 0;
else
{
for(int j=pos+1;j<size;j++)
{
if(str[pos+1]>='a'&&str[pos+1]<='z')
{
if(str[j]=='.') 
pos1=j;
}
else
return 0;
}
}
if(pos1==0)
return 0;
else
{
for(int k=pos1+1;k<size;k++)
{
if(str[k]>='a'&&str[k]<='z')
c++;
else
return 0;
}
if(c>=2)
return 1;
else
return 0;
}                                           
}                                           //end of function

int main()
{
int c;
char email[100],ch;
do
{
cout<<"\nEnter email: ";
cin.get(email , 100)    ;                                 //accepting email from user
c=email_check(email);
if(c==1)                     //if all criteria matched
{
cout<<"\nemail accepted...\n";

cout<<"\nYour email address is: ";
puts(email);
break;
}
else                               //criteria not matched
{
cout<<"\nInvalid email";
cout<<"\n\nWant to re-enter email(y/n): ";
cin>>ch;
}
}while(ch=='y'||ch=='Y');   //user is asked to enter again until the choice is yes
return 1;
}


int strLength(char str[]) {

    int k = 0;
    for(k = 0 ; ;k++){
        if(str[k] == '\0')
            break;
    }
    return k;
}

when you search the @ character, then after that instead of searching '.' from beginning of the string, you can start from the previous value of i variable.

Note:- I did not think much on this and all other cases.

user10513642

It should be:

if(ptr2 != 0 && &ptr2 >&ptr)

instead of:

if(ptr2 != 0 && &ptr2 < &ptr)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!