使用sscanf()格式说明符验证电子邮件地址

时间:2014-05-09 19:17:21

标签: c email-validation scanf format-specifiers

这可能有点像修复我的代码"问题,但我查看了documentationexamplesdozensofrelatedquestions,尽管我逻辑上或多或少地了解它是如何工作的,我无法将其转换为C sscanf()格式代码。我仍然是C的新手,我刚刚开始略微超越简单化的东西,而且我无法找出更复杂的格式说明符(即。%[^...]等)。

无论如何,这就是我所拥有的:

char user[EMAIL_LEN];
char site[EMAIL_LEN];
char domain[4];
if(sscanf(input, "%s@%s.%3s", user, site, domain) != 3){
  printf("--ERROR: Invalid email address.--\n");
}

为什么不起作用?我只想尝试一种简单的aaaa@bbbb.ccc格式,但出于某种原因,sscanf(input, "%s@%s.%3s", user, site, domain)始终评估为1。我是否需要使用一些疯狂的%[^...]魔法才能正确转换?我一直在捣乱%[^@]这类事情,但我似乎无法让它发挥作用。

感谢任何和所有帮助。谢谢!

1 个答案:

答案 0 :(得分:4)

scanf格式的

%s会跳过前导空格,然后匹配所有非空白字符,直到不包括下一个空格字符。因此,当您向其提供电子邮件地址时,则整个地址会被复制到user以匹配%s。然后,由于下一个字符不是@,因此不再匹配,scanf返回1.

您可以尝试使用以下内容:

sscanf(input, "%[^@ \t\n]@%[^. \t\n].%3[^ \t\n]", user, site, domain)

这将匹配作为用户的@或空格的所有内容,然后,如果下一个字符实际上是@将跳过它并将所有内容存储到. site中的空格或空格。但是这将接受许多其他在电子邮件地址中无效的字符,并且不会接受更长的域名。更好的可能是:

sscanf(input, "%[_a-zA-Z0-9.]@%[_a-zA-Z0-9.]", user, domain)

将接受名称和域的任何字母,数字,下划线和句点字符串。然后,如果您确实需要拆分域的最后一部分,请单独执行此操作。