// studentClass implementation #include "studentClass.h" // PRIVATE METHODS: void studentClass::assignAddress() { addressData = ""; // start with blank // write first two lines of address to addressData: if( addressDataB.lineA != "" ) addressData += "\t" + addressDataB.lineA; if( addressDataB.lineB != "" ) addressData += "\n\t" + addressDataB.lineB; if( addressDataB.city != "" || addressDataB.state != "" || addressDataB.zip != "" ) // check if city, state, or zip is defined { if( addressDataB.lineA != "" || addressDataB.lineB != "" ) // add a newline if address lines 1 or 2 are defined addressData += '\n'; addressData += '\t' + addressDataB.city; // write city if( addressDataB.city != "" && (addressDataB.state != "" || addressDataB.zip != "" ) ) addressData += ", " + addressDataB.state + ' ' + addressDataB.zip; // use a comma before state and zip if city is defined else addressData += addressDataB.state + ' ' + addressDataB.zip; // no comma } } void studentClass::zipCode( istream& inStream ) { int tempInt; // zipcode temp storage if( inStream >> tempInt ) // make sure an in is read { ostringstream tempOStream; // stores zip tempOStream << setfill('0') << setw(5) << tempInt; // write leading zeros and zip if( tempOStream.str().length() != 5 ) // make sure zip is 5 digits return; addressDataB.zip = tempOStream.str(); assignAddress(); } } void studentClass::state( istream& inStream ) { getline( inStream, addressDataB.state ); assignAddress(); } void studentClass::city( istream& inStream ) { getline( inStream, addressDataB.city ); assignAddress(); } // PUBLIC METHODS: // MUTATORS: bool studentClass::readAll( istream& inStream ) { // start with blank flags: emailData = otherData = nameData = addressData = phoneData = ""; addressDataB.lineA = addressDataB.lineB = addressDataB.city = addressDataB.state = addressDataB.zip = ""; string label; // field flag getline( inStream, label ); // initial field flag read while( inStream && label != "@@" ) // check for end of data { if( label[0] == '@' && inStream.peek() != '@' ) // check for empty field if( label == "@E-mail:" ) email( inStream ); else if( label == "@Name:" ) name( inStream ); else if( label == "@Phone Number:" ) phone( inStream ); else if( label == "@Address Line 1:" || label == "@Address Line 2:" ) address( inStream ); else if( label == "@City:" ) city( inStream ); else if( label == "@State:" ) state( inStream ); else if( label == "@Zipcode:" ) zipCode( inStream ); else if( label == "@Other:" ) other( inStream ); else assert( false ); // end program if unrecognized flag getline( inStream, label ); // read next flag } if( emailData == "" ) // make sure email address is present, all other fields are optional { flagData = false; phoneData = -1; emailData = otherData = nameData = addressData = ""; return false; } flagData = true; // flag this as valid return true; } bool studentClass::phone( istream& inStream) { char tempChar; // markers in phone number int tempInt; // numbers in phone number string tempString; // whole phone number getline( inStream, tempString ); // read in line stringstream tempStream( tempString ); // convert to stream so bad format will not throw off reading rest of data // read ints and chars in order to check that phone number format is correct: if( tempStream >> tempChar && tempStream >> tempInt && tempStream >> tempChar && tempStream >> tempInt && tempStream >> tempChar && tempStream >> tempInt && tempString.length() == 14 ) phoneData = tempString; else return false; return true; } bool studentClass::email( istream& inStream) { assert( emailData == "" ); // quit if duplicate email addresses for same student getline( inStream, emailData ); return inStream && emailData.length() > 0; // make sure an address has been read } bool studentClass::other( istream& inStream) { getline( inStream, otherData ); return inStream && otherData.length() > 0; } bool studentClass::name( istream& inStream) { getline( inStream, nameData ); return inStream && nameData.length() > 0; } void studentClass::address( istream& inStream) { if( addressDataB.lineA != "" ) // check that address line 1 has been read before reading into line 2 getline( inStream, addressDataB.lineB ); else getline( inStream, addressDataB.lineA ); assignAddress(); } // ACCESSORS: string studentClass::print() const { ostringstream tempOStream; // student info stream if( nameData != "" ) tempOStream << name(); if( phoneData != "" ) tempOStream << phone(); if( emailData != "" ) tempOStream << email(); if( addressData != "" ) tempOStream << address(); if( otherData != "" ) tempOStream << other(); return tempOStream.str() + '\n'; } // CONSTRUCTORS: studentClass::studentClass() { flagData = false; // flag unitialized emailData = otherData = nameData = addressData = phoneData = ""; // set blank flag data } studentClass::studentClass( istream& inStream ) { readAll( inStream ); } // EXTERNAL OPERATORS: bool operator >>( istream& inFile, studentClass& student ) { istringstream tempIStream( copyCommand( inFile ) ); // get a copy of the first student data from inFile return student.readAll( tempIStream ); // read the student data into student } bool operator <<( ostream& outFile, const studentClass& STUDENT ) { outFile << STUDENT.print(); return outFile; }