2012-07-23 96 views
1

我已經編寫了一個程序,在一個文本文件中查找有效的電子郵件地址,該文件中有許多電子郵件,其中有效的&無效。C++ subString POS

&然後在另一個文本文件中輸出vaild電子郵件。

我遇到的問題是創建一個子字符串或對象,它將讀取@符號&左邊的行,如果有多個「。」,則爲true。

例如:閱讀這行文字作爲一個有效的電子郵件 - [email protected]

&

,如果有更多的 '' @符號讀取爲false後。 這裏是我的代碼:

#include<iostream> 
#include<string> 
#include<fstream> 
using namespace std; 
const string DEFAULT_INPUT_FILENAME="fileContainingEmails.txt"; 
const string DEFAULT_OUTPUT_FILENAME="copyPasteMyEmails.txt"; 
const int N=1000; //assuming atmost 1000 email 

//function prototypes 
bool isNotDuplicateEmail(string emails[], int emailCount, string emailTemp); 
bool isValidEmail(string emails[], string emailTemp); 
void WriteToFile(string emails[], int emailCount, string outputFile); 
void DisplayEmailsToConsole(string emails[], int emailCount); 
bool isValidEmailChar(char c); 
int countOccurenceOfAt(string emailTemp); 
int countOccurenceOfDot(string emailTemp); 

int main() 
{ 
    //variable declaration 
    ifstream fin; 
    string inputFile; 
    string outputFile; 
    int emailCount=0; 
    string emails[N]; 


    //ask user for input and output file name 
    cout<<"Enter input file name: "; 
    getline(cin,inputFile); 
    cout<<"Enter output file name: "; 
    getline(cin,outputFile); 

    //check for default names 
    if(inputFile=="") 
     inputFile=DEFAULT_INPUT_FILENAME; 
    if(outputFile=="") 
     outputFile=DEFAULT_OUTPUT_FILENAME; 

    cout<<"Input File Name = "<<inputFile<<endl; 
    cout<<"Output File Name = "<<outputFile<<endl; 

    //open input file 
    fin.open(inputFile.c_str()); 
    //if file does not exists, display error message and return 
    if(!fin) 
    { 
     cout<<"ERROR: "<<inputFile<<" doen not exists."<<endl; 
     return 1; 
    } 

    string emailTemp; 
    /*read each line from file, and if it is not a duplicate email and a valid email 
    then add it to email list and increment count*/ 
    while(getline(fin,emailTemp)) 
    { 
     if(isNotDuplicateEmail(emails,emailCount,emailTemp) && isValidEmail(emails,emailTemp)) 
     { 
      emails[emailCount]=emailTemp; 
      emailCount++; 
     } 
    } 
    //close input file 
    fin.close(); 

    //call function to write emails to output file and console 
    if(emailCount>0) 
    { 
     WriteToFile(emails, emailCount, outputFile); 
     cout << endl << emailCount << " email addresses were found, and copied to the file " << outputFile<<endl; 
     DisplayEmailsToConsole(emails, emailCount); 
    } 
    else 
    { 
     cout << "Sorry, no email addresses were found in the file " << inputFile << endl; 
    } 


    cout << endl<< "Press ENTER to continue..." << endl; 
    cin.get(); 
    return 0; 
} 

bool isNotDuplicateEmail(string emails[], int emailCount, string emailTemp) 
{ 
    /*Check each email address and if a duplicate email is found, return false*/ 
    /*If email is not a duplicate email, return true*/ 
    for(int i=0;i<emailCount;i++) 
    { 
     if(emailTemp==emails[i]) 
      return false; 
    } 
    return true; 
} 
bool isValidEmail(string emails[], string emailTemp) 
{ 
    if(emailTemp=="") 
     return false; 
    /*If there are more than 1 @*/ 
    if (countOccurenceOfAt(emailTemp)!=1) 
     return false; 
    /*If there are more than 1 .*/ 
    if(countOccurenceOfDot(emailTemp)!=1) 
     return false; 


    int index1=-1; 
    int index2=-1; 


    //check each character for valid email char 
    for (int i=0; i<emailTemp.size(); i++) 
    { 
     if(!isValidEmailChar(emailTemp[i])) 
      return false; 
    } 

    //find index of @ and . 
    index1=emailTemp.find_first_of('@'); 
    index2=emailTemp.find_first_of('.'); 

    if(index1<1) 
     return false; 
    if(index2<index1) 
     return false; 
    if((index2-index1)==1) 
     return false; 

    if(((emailTemp.size()-1)-index2)==0) 
     return false; 

    return true; 
} 

bool isValidEmailChar(char c) 
{ 
    /* check for valid email characters 0-9, @, ., A-Z, a-z, _, +, - */ 
    if(c>='0' && c<='9') 
     return true; 
    if(c>='A' && c<='Z') 
     return true; 
    if(c>='a' && c<='z') 
     return true; 
    if(c=='@' || c=='.' || c=='_' || c=='+' || c=='-') 
     return true; 

    return false; 

} 

/*Function to count occurence of @ in email address*/ 
int countOccurenceOfAt(string emailTemp) 
{ 
    int count=0; 
    for(int i=0;i<emailTemp.size();i++) 
    { 
     if(emailTemp[i]=='@') 
      count++; 
    } 
    return count; 
} 

/*Function to count occurence of . in email address*/ 
int countOccurenceOfDot(string emailTemp) 
{ 
    int count=0; 
    for(int i=0;i<emailTemp.size();i++) 
    { 
     if(emailTemp[i]=='.') 
      count++; 
    } 
    return count; 
} 

void DisplayEmailsToConsole(string emails[], int emailCount) 
{ 
    /*Display console message and then display each email address, one at a line*/ 
    cout << endl << endl << "You can open the output file and copy/paste its contents into the \"to\", \"cc\", or \"bcc\" field of any email message. It is best to use the \"bcc\" field so that everyone's email address does not appear in the message, to protect their privacy"<<endl; 
    cout << endl << "Email List is: "<< endl; 
    for (int i=0; i<emailCount; i++) 
    { 
     cout << emails[i] << endl; 
     cout << endl; 
    } 
} 

void WriteToFile(string emails[], int emailCount, string outputFile) 
{ 
    /*Open file and write each email address to output file followed by ; */ 
    ofstream fout; 
    fout.open(outputFile.c_str()); 
    for(int i=0; i<emailCount; i++) 
    { 
     fout << emails[i] << "; " << endl; 
    } 
    //close file 
    fout.close(); 
} 
+6

這是很多代碼。你應該把它縮小一點,'WriteToFile' f.ex.在關於子串和輸入驗證的問題中只是噪聲。 (恕我直言) – jrok 2012-07-23 17:54:59

+0

看看這個其他問題:http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address – betabandido 2012-07-23 18:09:22

回答

1

如果你需要知道的是,如果有@符號前面多期,然後就去做:

if (email.find_first_of('.') == email.find_last_of('.')) 

如果表達式返回true,那麼你就知道該字符串只有一個週期(或沒有)。

+0

@符號之前的@符號?這會爲「[email protected]」返回false。 – Marlon 2012-07-23 18:16:54

+0

讓「email」等於@符號前的地址部分。所以,讓「email」等於「Jimmy.Cole」 – 2012-07-23 18:21:33

+0

嘿邁克,我不知道我應該在哪裏放置這行代碼。我有一個文本文件中只有有限數量的有效或真實電子郵件的多個電子郵件。我的程序讀取真正的電子郵件罰款1例外。它不能閱讀電子郵件,如[email protected] bc。在@符號之前。我似乎無法找到正確的路線來放置此。我覺得我的腦袋超負荷或什麼的。 – 2012-07-23 20:41:03

1

下面的代碼是從書Secure Programming Cookbook for C and C++

#include <string.h> 

int spc_email_isvalid(const char *address) { 
    int  count = 0; 
    const char *c, *domain; 
    static char *rfc822_specials = "()<>@,;:\\\"[]"; 

    /* first we validate the name portion ([email protected]) */ 
    for (c = address; *c; c++) { 
    if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) == 
     '\"')) { 
     while (*++c) { 
     if (*c == '\"') break; 
     if (*c == '\\' && (*++c == ' ')) continue; 
     if (*c <= ' ' || *c >= 127) return 0; 
     } 
     if (!*c++) return 0; 
     if (*c == '@') break; 
     if (*c != '.') return 0; 
     continue; 
    } 
    if (*c == '@') break; 
    if (*c <= ' ' || *c >= 127) return 0; 
    if (strchr(rfc822_specials, *c)) return 0; 
    } 
    if (c == address || *(c - 1) == '.') return 0; 

    /* next we validate the domain portion ([email protected]) */ 
    if (!*(domain = ++c)) return 0; 
    do { 
    if (*c == '.') { 
     if (c == domain || *(c - 1) == '.') return 0; 
     count++; 
    } 
    if (*c <= ' ' || *c >= 127) return 0; 
    if (strchr(rfc822_specials, *c)) return 0; 
    } while (*++c); 

    return (count >= 1); 
}