Need some help with my into to c++ final project

Discussion in 'OT Technology' started by BlackWRX, May 20, 2008.

  1. BlackWRX

    BlackWRX New Member

    Joined:
    Apr 25, 2002
    Messages:
    25,574
    Likes Received:
    0
    Location:
    Bay Area, CA
    I am making a program that reads lines from a text file, finds email addresses in the file, and saves them to a list and then outputs them to another file. Here is the actual problem:

    Write a program named email.cpp that opens and reads a text file and writes another text file. The purpose of the program is to extract email addresses embedded in the first (input) text file, and copy them to the second (output) text file. The application of the program is to make it easier to enter email addresses into an email message that is to be sent to a list of recipients, when those recipients are not already in a contacts list.

    Here are the specifications for the program:

    1. There are to be two console inputs to the program, as explained below. For each input, there is to be a default value, so that the user can simply press ENTER to accept any default. (That means that string will be the best choice of data type for the console input for each option.)

    2. Two console inputs are the names of the input and output files. The default filenames are to be fileContainingEmails.txt for the input file, and copyPasteMyEmails.txt for the output file. The default location for these files is the working folder of the program (so do not specify a drive or folder for the default filenames). The actual names and locations of the files can be any valid filename for the operating system being used, and any existing drive and folder.

    3. It is okay for the user to select input and output names by the same name. If the user enters another name for the input file besides the default, then the default for the output file should change to be the same as that of the input file. So if the input and output filenames are the same, then the input file becomes replaced by the output file when the program is run.

    4. The output file should be overwritten, and not appended to. No warning is necessary when overwriting an already-existing file.

    5. Print each email to the output file, separated by a semicolon and a space. Include nothing before the first email message, and nothing after the last. Include nothing in the file besides email addresses and semicolon+space separators.



    7. Count the number of email addresses found as the input file is processed, and list each on a separate line of console output. At the end of the list of email addresses on the console, print the total number of email addresses found (not counting any duplicates). If the number of email addresses found is zero, do not write the output file. (That means, do not even open it.)

    8. In case an email address is split between two or more lines in the input file, ignore it. Valid email addresses must appear fully within one line of the input file. Also, each line of the input file may contain more than one email address.

    9. Include friendly, helpful labels on the console output. Instead of just printing the number of email addresses found, say something like "16 email addresses were found, and copied to the file output.txt". Or if none were found, say something like "Sorry, no email addresses were found in the file input.txt".

    10. Include a message in the console output explaining to the user to open the output file and copy/paste its contents into the "to", "cc", or "bcc" field of any email message. But explain that it is best to use the "bcc" field so that everyone's email address does not appear in the message, to protect their privacy.


    Here is my code so far, I just need some ideas on how to find the email addresses because I am lost.

    Code:
    #include <fstream>
    #include <iomanip>
    #include <iostream>
    #include <string>
    using namespace std;
    
    struct Email
    {
      string line;
      string address;
      Email* next; 
    }; // Email
    
    int main()
    {
      //Two inputs with default values
      ifstream fin; // fin
      string inFileName = "fileContainingEmails.txt"; //default value
      string outFileName = "copyPasteMyEmails.txt"; // default value
      string tempName;
      
      // Prompt for names other than default
      while(true)
      { 
        cout << "What file do you want to use for input? [ENTER for default]: ";
        getline(cin, tempName);
        
        if (tempName == "") break;
        
        inFileName = tempName;
        outFileName = tempName;
        
        break;
      } 
      
      // Create an empty list
      Email* head = 0;
      
      // Open input file for processing     
      fin.open(inFileName.c_str());
      
      // Read data
      while (fin.good())
      {
        Email* aEmail = new Email;
        
        // Find email in file
        getline(fin, aEmail->line);
    
        // Need to add code to find the actual email here
        // If email is found, add to front of the list below
        
        // Add to front of list
        aEmail->next = head;
        head = aEmail;
      }
      
      // Close file when done storing data to list
      fin.close();  
      
      // Output and overwrite without warning
      ofstream fout;
      fout.open(outFileName.c_str());
      if (!fout.good()) throw "I/O error";  
      
      // Output email addresses with ; and space
      Email* p;
      for (p = head; p; p = p->next)
      {
        cout << p->address << endl;
        fout << p->address << "; ";
      } // for
    
      // Close output file
      fout.close();
    
     [B][B]// release borrowed memory
     while(head)
     {
       Email* next = head->next;
       delete head;
       head = next;
     } // while
    [/B][/B]
    return 0;
    }
    
    
    Here are some hints for finding email addresses he gave us:

    * Read a line from the input file as string line;. Traverse it, testing each line until you find a '@'. Then look backwards in a loop until you find an invalid email address character, or run into the start of line. Then look forwards from the same '@' in another loop until you find an invalid email address character, or run into the end of line. When looking forwards, be sure to count the number of dots ('.') found -- there needs to be at least one in a valid email address.

    * To build an email address embedded in a string, create a separate string address = "";. Then concatenate it with extracted char values from line.

    * Use an Array-Based List (Chapter 12) to store found email addresses. Let the list capacity be a large number, like 1000, to fit up to that many email addresses. Search this list, using a "Boolean Search Loop", to avoid adding duplicate addresses. You may use one of the unlimited-size lists from Chapter 13 or 14, if you prefer.

    * Write a value-returning function for testing a character to see if it is a valid email address character. For example, bool isValidEmailCharacter(char c). In it, test to see if "c" is >='A' and <='Z', or >='a' and <='z', >='0' and <='9', or =='.', or =='-', or =='+'. If it satisfies any of these conditions, return true. Otherwise, return false.


    I am not looking for someone to finish this for me, I am just a bit lost and need some ideas. All I really need are ideas to find and extract the email addresses, I can figure the rest out on my own.
     
    Last edited: May 21, 2008
  2. BlackWRX

    BlackWRX New Member

    Joined:
    Apr 25, 2002
    Messages:
    25,574
    Likes Received:
    0
    Location:
    Bay Area, CA
    Read a line from the input file as string line;. Traverse it, testing each line until you find a '@'. Then look backwards in a loop until you find an invalid email address character, or run into the start of line. Then look forwards from the same '@' in another loop until you find an invalid email address character, or run into the end of line. When looking forwards, be sure to count the number of dots ('.') found -- there needs to be at least one in a valid email address.

    All I really need is that right there. Anyone?
     
  3. BlackWRX

    BlackWRX New Member

    Joined:
    Apr 25, 2002
    Messages:
    25,574
    Likes Received:
    0
    Location:
    Bay Area, CA
    Never mind I got it.

    If anyone is interested here is the final code:

    Code:
    #include <fstream>
    #include <iomanip>
    #include <iostream>
    #include <string>
    using namespace std;
    
    //Function to check for valid email characters
    bool validEmail(char c)
    { 
      bool result = false;
      if
      (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_' || c == '-'  || c == '.')
      result = true;
      return result;  
    }// isValid
        
    int main ()
    {
    
    //Declare a list
      const int MAX_EMAILS = 1000; // capacity
      int nEmails = 0; // initially empty
      string email[MAX_EMAILS]; 
    
    //Open input File
     //Two inputs with default values
      ifstream fin; // fin
      string inFileName = "fileContainingEmails.txt"; //default value
      string outFileName = "copyPasteMyEmails.txt"; // default value
      string tempName;
      
      // Prompt for names other than default
      while(true)
      { 
        cout << "What file do you want to use for input? [ENTER for default]: ";
        getline(cin, tempName);
        
        if (tempName == "") break;
        
        inFileName = tempName;
        outFileName = tempName;
        
        break;
      } 
      
      fin.open(inFileName.c_str());
    
    //Process each line
      while (fin.good())
      {
        // Get line from file
        string lineFromFile;
        getline(fin, lineFromFile);
        
        //If character at i is @
        int i;
        for (i = 0; i < lineFromFile.length(); i++)
          if (lineFromFile[i] == '@')
          { 
            int s = i; //create s and set to i
            while(true)
            {
              s--;
              if (s < 0) break;
              if (validEmail(lineFromFile[s]) == false)
                break;
            }
            s++; // increment s
            int e = i; //create e and set to i
            bool hasDot = false; // create hasDot 
            while(true)
            {
              e++; // increment e
              if (lineFromFile[e] == lineFromFile.length()) break;
              if (validEmail(lineFromFile[e]) == false) break;
              if (lineFromFile[e] == '.') hasDot = true;
            }
            
            if (s < i && e > i && hasDot == true)
            {
              string aEmail = lineFromFile.substr(s, e-s);
              if (nEmails < MAX_EMAILS)    
                email[nEmails++] = aEmail;
            }
    
             }
      }
    //Close input file
      fin.close();  
    
    //If list is empty
    
      ofstream fout;
      fout.open(outFileName.c_str());
      if (!fout.good()) throw "I/O error";  
        
      if (nEmails == 0)
          cout << "\nSorry, there were no addresses found in the file." << endl;
          cout << "Please try running the program again with another file." << endl;
      
      if (nEmails > 0)
      {
        int i;
        for (i = 0; i < nEmails; i++)
          {
                 fout << email[i] << "; "; 
                 cout << email[i] << endl;
          }
        cout << "\nThere were " << nEmails << " emails found in the file. All addresses were copied to " << outFileName.c_str() << "\n";
        cout << "\nTo use the addresses, open the file " << outFileName.c_str() << " and copy the contents to the 'to, cc, or bcc' fields of your email program.";
        cout << "\n\nIt is best to use the BCC field to avoid all recipients seeing all of the email addresses.\n";
      }
    
    //Close output file
      fout.close();
    
      return 0;
    }
    
     
  4. ge0

    ge0 New Member

    Joined:
    Oct 31, 2005
    Messages:
    8,398
    Likes Received:
    0
    Location:
    JERSEY
    you couldn't use classes?
     
  5. BlackWRX

    BlackWRX New Member

    Joined:
    Apr 25, 2002
    Messages:
    25,574
    Likes Received:
    0
    Location:
    Bay Area, CA
    it's an intro to c++ class
     
  6. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    Sounds more like intro to C?
     
  7. Bruticus

    Bruticus half dead OT Supporter

    Joined:
    Apr 10, 2004
    Messages:
    4,608
    Likes Received:
    0
    Location:
    Melbourne
    Least he did his own work :)
     
  8. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    Tru dat
     

Share This Page