在回顾我的代码时,我的教授说我使用strstr
和strchr
会导致大量的资源浪费,因为每一个都在扫描字符串。
我能以一种好的方式减少函数的数量吗?
此代码扫描字符串,并根据设置的参数确定输入是否有效。ch1
是'@'
并且ch2
是'.'
,(email[i]
)是字符串。
for (i = 0; email[i] != 0; i++) {
{
if (strstr(email, "@.") ||
strstr(email, ".@") ||
strstr(email, "..") ||
strstr(email, "@@") ||
email[i] == ch1 ||
email[i] == ch2 ||
email[strlen(email) - 1] == ch1 ||
email[strlen(email) - 1] == ch2) {
printf("The entered e-mail '%s' does not pass the required parameters, Thus it is invalid\n", email);
} else {
printf("The email '%s' is a valid e-mail address\n",email);
}
break;
}
}
这是我在说的片段。
我应该编写自己的代码来检查一次吗?如果是的话,你能给我一些建议吗?
谢谢您。
编辑:非常感谢您的回复,我确实学到了代码中的错误,希望我能从中吸取教训。
再次感谢!
编辑:2:我想再次感谢你的回复,他们对我帮助很大,我相信我已经写了更好的代码
int at_count = 0, dot_count = 0, error1 = 0, error2 = 0;
int i;
size_t length = strlen(email);
int ch1 = '@', ch2 = '.';
for ( i = 0; email[i] != '\0'; i++) /* for loop to count the occurance of the character '@' */
{
if ( email[i] == ch1)
at_count++;
}
for ( i = 0; email[i] != '\0'; i++) /* for loop to count the occurance of the character '.' */
{
if ( email[i] == ch2)
dot_count++;
}
if ( email[0] == ch1 || email[0] == ch2 || email[length-1] == ch1 || email[length-1] == ch2 )
{
error1++;
}
else
{
error1 = 0;
}
if ( strstr(email,".@") || strstr(email, "@.") || strstr(email, "..") || strstr(email, "@@"))
{
error2++;
}
else
{
error2 = 0;
}
if ( (at_count != 1) || (dot_count < 1) || (error1 == 1) || (error2 == 1))
{
printf("The user entered email address '%s' is invalid\n", email);
}
else
{
printf("'%s' is a valid email address\n", email);
}
我觉得这是更优雅更简单的代码,也更高效。
我的主要灵感来自@chqrlie,因为我觉得他的代码非常好,而且很容易阅读。
我还有什么可以改进的吗?
(邮件检查只是为了练习,别介意!)
非常感谢大家!
最佳答案
您的代码确实有多个问题:
for (i = 0; email[i] != 0; i++) { // you iterate for each character in the string.
{ //this is a redundant block, remove the extra curly braces
if (strstr(email, "@.") || // this test only needs to be performed once
strstr(email, ".@") || // so does this one
strstr(email, "..") || // so does this one
strstr(email, "@@") || // again...
email[i] == ch1 || // this test is only performed once
email[i] == ch2 || // so is this one
email[strlen(email) - 1] == ch1 || // this test is global
email[strlen(email) - 1] == ch2) { // so is this one
printf("The entered e-mail '%s' does not pass the required parameters, Thus it is invalid\n", email);
} else {
printf("The email '%s' is a valid e-mail address\n", email);
}
break; // you always break from the loop, why have a loop at all?
}
}
您可以扫描字符串4次来测试各种模式,另外2次来测试
strlen()
。应该可以在一次扫描过程中执行相同的测试。还要注意,更多的问题没有被注意到:
应该有一个
不应该有任何空格
一般来说,地址中允许的字符是有限的。
有些测试似乎有点过头了:为什么在
@
之前拒绝..
,为什么在@
之前拒绝后面的.
?下面是一个更有效的版本:
int at_count = 0;
int has_error = 0;
size_t i, len = strlen(email);
if (len == 0 || email[0] == ch1 || email[0] == ch2 ||
email[len - 1] == ch1 || email[len - 1] == ch2) {
has_error = 1;
}
for (i = 0; !has_error && i < len; i++) {
if (email[i] == '.') {
if (email[i + 1] == '.' || email[i + 1] == '@') {
has_error = 1;
}
} else if (email[i] == '@') {
at_count++;
if (i == 0 || i == len - 1 || email[i + 1] == '.' || email[i + 1] == '@') {
has_error = 1;
}
}
// should also test for allowed characters
}
if (has_error || at_count != 1) {
printf("The entered e-mail '%s' does not pass the required tests, Thus it is invalid\n", email);
} else {
printf("The email '%s' is a valid e-mail address\n", email);
}