Well the code was well-commented on the easy stuff, such as
//if user press enter key
but there were few clues to the algorithm in the most important part. The first thing I figured out that
s
and
e
were meant to identify the start and end of a possible email.
Anyway - the code. A couple of the loops start from the position of the '@' symbol which immediately fails all the tests in
isValidEmailCharacter()
, so the loop start needs to be adjusted by one position forwards or backwards. The logic around the finding of a dot is a bit flawed, it should not stop (break) when finding a dot, there may be more characters to follow. Better to set a boolean
dotFound
to assist with that. The main loop searching for the '@' symbol doesn't need to bother trying to output an email if there was no '@', you could add a
continue
to bypass the rest of that code.
One more thing, the loop to read the lines from the file is better written in this idiom:
1 2 3 4 5
|
while (getline(fin, lineFromFile))
{
// do some processing of the line here
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
while (getline(fin, lineFromFile))
{
// First, search for '@' character
for (int i = 0; i < lineFromFile.length(); i=i+1)
{
if (lineFromFile[i] != '@')
continue;
// Identfy start of previous part of email
int start; // start of possible email
for (start = i-1; start >= 0; --start)
{
if (!isValidEmailCharacter(lineFromFile[start]))
break;
}
++start;
// identify end of next part of email
bool dotFound = false;
int end; // end of possible email
for (end = i+1; end < lineFromFile.length(); ++end)
{
if (!isValidEmailCharacter(lineFromFile[end]))
break;
if (hasDot(lineFromFile[end]))
dotFound = true;
}
// final reasonableness check
// Note: consecutive dots are allowed
if (start < i && end > i && dotFound)
{
string anEmail = lineFromFile.substr(start, end-start);
cout << anEmail << endl;
}
}
}
|