2016-04-28 13 views
2

私はユーザーが自分の電子メールを入力できるようにするプログラムを作ろうとしています。彼らの電子メールは、2つの条件が満たされている場合に有効と見なされます。A.そこには「@」記号があり、Bには「@」の後にピリオドが必要です。私は大部分のコードをダウンしましたが、 "@"記号の前にあるピリオドを持つ電子メールの検証にはいくつかの問題があります。 「@」記号の前にピリオドがある場合は有効とみなされますが、そうではありません。たとえば、[email protected]と入力すると有効と見なされます。C++で電子メールの検証

誰かが私が間違っていたことを理解するのを助けることができますか?前もって感謝します!

#include <iostream> 
#include <cctype> 
#include <cstring> 
using namespace std; 

int main() 
{ 
    int x = 25; //random size enough to hold contents of array plus one for    null terminator 
    char input[x]; //array to hold input 
    int sizeOf; //holds length of input array 
    char* ptr = nullptr; //pointer 
    char* ptr2 = nullptr; //pointer 

    cout << "Enter your email address\n"; 
    cin.getline(input,x); 
    sizeOf = strlen(input); 

    for(int i = 0; i < sizeOf; i++) 
    { 
     ptr= strstr(input, "@"); //searches input array for "@" string 
     if(ptr != nullptr) 
     { 
      break; 
     } 
    } 

    for(int i = 0; i < sizeOf; i++) 
    { 
     ptr2 = strstr(input, "."); //searches input array for "." string 
     if(ptr2 != nullptr && &ptr2 > &ptr) 
     { 
      break; 
     } 
    } 

    if(ptr != nullptr) //validates input of "@" sign 
    { 
     if(ptr2 != 0 && &ptr2 < &ptr) 
      { 
       cout << "Email accepted.\n"; 
      } 

     else 
      { 
       cout << "Missing . symbol after @\n"; 
      } 
    } 

    else 
    { 
     cout << "Missing @ symbol\n"; 
    } 



return 0; 
} 
+1

メールアドレスのための25文字バッファ?私は泣かなければならないかどうか分からない。あなたのプログラムは、誰かがそれより長いアドレスを入力するような大胆さを持つとすぐに、急な列車を未定義の行動に乗ります。 'oblivion @ eternaloblivion.com'はあなたのコードには長すぎる長さの短いアドレスです。これが、固定長のCスタイルバッファが本当に悪いニュースである理由です。 – tadman

+3

これは「電子メールのサブセットの検証」であり、電子メールの検証は[驚くほど複雑です](http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html)という誤解を招く可能性があります。 。 – user657267

+0

一部の電子メールアドレスにはドメイン内にドットが含まれていない場合があります。詳細はRFC2822を参照してください。電子メールアドレスの検証はタールベビーです。 – jbruni

答えて

1

ここでの主な問題は、これはC++プログラムであると考えられていますが、代わりにCプログラムになりました。 strstr()とstrlen()はCライブラリ関数です。

最新のC++では、std::string、イテレータ、アルゴリズムを使用しています。これにより、タスク全体が大幅に短縮され、grokが簡単になります。バッファオーバーフローについて心配する必要はありません。

#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; 
} 

ここで、それほど短くはなく、解析が簡単ですか?

+0

その '条件 'は、多くの単なる人間の手の届かないものです。それが正しいことを確かめるために私はそれを数回読まなければならなかった。理解しにくいです。 –

+0

私の心は神秘的な仕方で働いています。 find()を使用するインデックスベースのソリューションを追跡するのではなく、イテレータの周りに脳をラップする方が簡単です。 –

+0

問題はイテレータの使用ではありません。イテレータは問題ありません。問題は、最初の条件が2番目の条件を変更する 'if'の二重条件です。代入の結果を3番目の値と比較することのボーナスをプラスします(しかし、少なくとも、適切な括弧を付け加えれば、あまり浸透しにくくなります)。 –

1

std::stringを使用してください。奇妙な固定サイズのC文字列ではありません。

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; 
} 
+1

私は' if(cin >> input){...} else {... err ... } ' - 先行/末尾/埋め込み空白(後に空白の内容が何らかの形で後で検証されることを前提とする)と空白を含まない行の問題を回避するか、またはそれが次の行であることを確認したい場合'getline'を使用し続けますが、成功したかどうかチェックし、空白を整える/空の' input'をチェックしてください。 –

6

なぜ正規表現を使用しないのですか?

#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 = "[email protected]"; 

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

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

+0

"今は2つの問題があります。" Stack Overflowを作成した人の礼儀です! http://blog.codinghorror。com/regular-expressions-now-you-have-two-problems/ –

+0

'@'の前に '.'または' _'をチェックしていますか?これは要件ではないが、残りは良好に見える。 –

関連する問題