 |
|
 |
FIXED:
BOOL WINAPI WfxIsValidEMail(LPCTSTR lpsz, int nLength /* = -1 */)
{
ASSERT(AfxIsValidString(lpsz, nLength));
if (nLength == -1) nLength = _tcslen(lpsz);
if (nLength < 5) return FALSE; // Too short
LPCTSTR pszTmp = _tcschr(lpsz, '@');
if (pszTmp == NULL || pszTmp == lpsz) { return FALSE; }
if (*(pszTmp + 1) == '.') { return FALSE; }
if (NULL != _tcschr(pszTmp + 1, '@')) { return FALSE; }
if (_tcsrchr(lpsz, '_') > pszTmp) { return FALSE; }
LPCTSTR pszDot = _tcsrchr(pszTmp, '.');
if (pszDot == NULL) { return FALSE; }
if (nLength - (pszDot - lpsz) > 4) { return FALSE; }
register const TCHAR* pch = lpsz;
while (*pch)
{
if ((*pch != '.') && (*pch != '@') && (!_istalnum(*pch)) &&
(*pch != '_') && (*pch != '-')) { return FALSE; }
pch++;
}
return TRUE;
}
|
|
|
|
 |
|
 |
Let's use Automate to validate e-mail address (or whatever you wish).
|
|
|
|
 |
|
 |
As a note, the actual definition of a well-formed E-Mail address can be found in RFC 822:
http://www.ietf.org/rfc/rfc0822.txt[^]
The Email::Valid[^] Perl module includes a (massive) regex for performing the match, which (I'm guessing) can probably be used with PCRE[^].
A nice addition to this article would be something else that Email::Valid does for E-Mail validation: performing a DNS lookup on the domain (the domain should have either an MX or an A record).
- Mike
|
|
|
|
 |
|
 |
It would be very interesting to get more of these lines. Programmers often need such tools. Good work, even if I've some remarks.
I propose to replace some lines with the next. I've found some things than can help. But there is a big problem, with phone numbers, in France we use 10 numbers, when I look up your code the phone number buffer can have 11 characters. I propose to get the current language ID and to retrieve the phone number length with a new function. Perhaps Windows already has this. I've posted a question today on "Ask to pro", and am waiting...
Thanks
Philippe RIO - phr39@wanadoo.fr
*****************************************************************************************************************************
#include "stdafx.h"
BOOL ValidateEMail(CString Address)
{
// Address = "A@b.c"; // Valid
// Address = "A@b.cnet"; // Invalid
// Address = "A@b.c_"; // Invalid
// Address = "A@bcnn"; // Invalid
// Address = "Ab.cnn"; // Invalid
// Address = "A@bc"; // Invalid
// Address = "A@bat@.cnn"; // Invalid
// Address = "A@bat/.com"; // Invalid
register int iPos ;
register int iNumChars ;
iNumChars = Address.GetLength() ;
if(iNumChars < 5) return (FALSE) ; // Too Short
if(Address.Find("@") == -1) return (FALSE) ; // Has at least 1 @
if(Address.Find(".") == -1) return (FALSE) ; // Has a Period
if(iNumChars - Address.ReverseFind('.') > 4) return (FALSE) ; // no more than 3 characters after the final period (reverse find is 0 based not 1 based)
if(Address.ReverseFind('_') > Address.ReverseFind('@')) return (FALSE) ; // an underscore after the @
// only 1 @
iPos = Address.Find("@") ;
if(Address.Find("@", iPos + 1) != -1) return (FALSE) ;
// allowed characters 0-9 A-Z _.@-
char c ;
iNumChars = Address.GetLength();
Address.MakeUpper();
for(iPos = 0 ; iPos < iNumChars ; iPos++)
{
c = Address[iPos] ;
if((!isalnum(c)) && (c != '_') && (c != '.') && (c != '@') && (c != '-'))
return (FALSE) ;
}
return (TRUE) ;
}
//*************************************************************************************************
//************************* useful code form MSDN *************************************************
//*************************************************************************************************
// This function detects a correct initial UI language for all
// platforms (Win9x, ME, NT4, Windows 2000, Windows XP)
LANGID DetectLanguage()
{
#define MAX_KEY_BUFFER 80
OSVERSIONINFO VersionInfo;
LANGID uiLangID = 0;
HKEY hKey;
DWORD Type, BuffLen = MAX_KEY_BUFFER;
TCHAR LangKeyValue[MAX_KEY_BUFFER];
VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if( !GetVersionEx(&VersionInfo) )
return(0);
switch( VersionInfo.dwPlatformId ) {
// On Windows NT, Windows 2000 or higher
case VER_PLATFORM_WIN32_NT:
if( VersionInfo.dwMajorVersion >= 5) // Windows 2000 or higher
uiLangID = GetUserDefaultUILanguage();
else { // for NT4 check the language of ntdll.dll
uiLangID = GetNTDLLNativeLangID();
if (uiLangID == 1033) { // special processing for Honkong SAR version of NT4
if (IsHongKongVersion()) {
uiLangID = 3076;
}
}
}
break;
// On Windows 95, Windows 98 or Windows ME
case VER_PLATFORM_WIN32_WINDOWS:
// Open the registry key for the UI language
if( RegOpenKeyEx(HKEY_CURRENT_USER,_T("Default\\Control Panel\\Desktop\\ResourceLocale"), 0,
KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS ) {
// Get the type of the default key
if( RegQueryValueEx(hKey, NULL, NULL, &Type, NULL, NULL) == ERROR_SUCCESS
&& Type == REG_SZ ) {
// Read the key value
if( RegQueryValueEx(hKey, NULL, NULL, &Type, (LPBYTE)LangKeyValue, &BuffLen)
== ERROR_SUCCESS ) {
uiLangID = _ttoi(LangKeyValue);
}
}
RegCloseKey(hKey);
}
break;
}
if (uiLangID == 0)
{
uiLangID = GetUserDefaultLangID();
}
// Return the found language ID.
return (uiLangID);
}
//*************************************************************************************************
//************************* useful code form MSDN (end) *******************************************
//*************************************************************************************************
int PerCountryGetPhoneLength(void)
{
switch(GetUserDefaultLangID())
{
case 0x040c : return (10) ; // French (Standard)
case 0x0409 : return (11) ; // English (United States)
.
.
.
default : return (0) ;
}
return (0) ;
}
BOOL ValidatePhone(CString FaxNum)
{
int iPhoneLen ;
char c ;
int iPos, iLast ;
int iNumChars ;
iNumChars = FaxNum.GetLength() ;
iPhoneLen = PerCountryGetPhoneLength() ;
if(iNumChars != iPhoneLen) return (FALSE) ;
FaxNum.MakeUpper() ;
iLast = 0 ;
for(iPos = 0 ; iPos < NumChars ; iPos ++)
{
c = FaxNum[iPos] ;
if(!isdigit(c))
{
if(!isspace(c)) return (FALSE) ;
if(!iPos) continue ;
if(FaxNum[iLast] == ' ') return (FALSE) ;
iLast++ ;
}
}
return (TRUE) ;
}
|
|
|
|
 |
|
 |
There are already domains in use that are outside of the
ASCII alphabet, so I imagine that there are or soon will
be email addresses that are outside of ASCII, which will
badly break your tests. You will need to (a) handle UTF-8
(or whatever) and (b) use much more advanced character set
testing.
|
|
|
|
 |
|
 |
A regular expression as simple as:
/.+\@.+\..+/
can do almost the same thing (Almost ). Take a look at Mastering Regular Expressions by Jeffrey E. F. Friedl (O'Reilly and Associates). Also, a nice C++ library called Regex++ kicks butt for these types of things. Some may say the overhead of linking in the library makes it overkill, but regular expressions are not only elegant, they are a lot of fun once you get used to them. Trust me, you'll find a use for them constantly.
Best Regards.
-Matt
|
|
|
|
 |
|
 |
If the program is already linking it maybe okay (but I don´t believe it).
If not, its the biggest bullsh*t ever to link to library to parse a string. (&& the code is great && M$ rulez)
|
|
|
|
 |
|
 |
KarstenK wrote:
If the program is already linking it maybe okay (but I don´t believe it).
If not, its the biggest bullsh*t ever to link to library to parse a string. (&& the code is great && M$ rulez)
Why is that bullsh*t? Hard drives are cheap. Who cares if it makes your exe bigger in the end? It'll run faster and be less likely to have buffer overruns, etc.
Usually the best way to write software is to use the right tool for the job. While using regular expressions for one string in an application may be overkill (you have a point there) and could be done almost as easily writing your own parser, it's certainly not an invalid choice. However, my point was that regular expressions are very useful and you will probably find more than one use for them once you *have* linked it into your project.
Now, if your point has to do with speed or benchmarking, I would gladly take that challenge. You write a parser in straight C, and I'll write one using a regular expression engine such as Regex++. Then we can compare which is the better solution based on three things: 1) the time it takes to create the parser, 2) efficiency, and 3) raw speed. Meanwhile, you should consider being a little more polite when you post a response here.
Just because someone doesn't write code the way *you* do, doesn't make it "the biggest bullsh*t" (whatever that means)--and it certainly doesn't make your way better. BTW, have you ever used regular expressions? Seems to me that to have an opinion on something, you should probably have used it first.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
 |
|
 |
perlmunger wrote:
Then we can compare which is the better solution based on three things:
A fourth thing would be how much work is involved when the input requirements change. I'd much rather change a regex string than to retool a whole validation function/routine.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
 |
|
 |
Good point. This thread is quite old, but that's definitely one point I should have mentioned.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
 |
|
|
 |