C 确定密码是否有效的代码的效率如何?

C 确定密码是否有效的代码的效率如何?,c,C,要求密码必须包含大写字母、数字和“$”符号。一切都可以工作(除了用户出于某种原因输入一个空格,所以请提供帮助),但是idk知道我的代码有多高效。我是C的新手,有什么建议吗?(还有什么方法可以为我的密码设置“最大长度”,而不仅仅是将其设置为非常高的值或强制用户遵守限制?) int main(无效){ int maxlength=15; 字符密码[maxlength]; int指数=0; int x=0; int y=0; int z=0; printf(“输入密码:”;//迈克$4 scanf(“

要求密码必须包含大写字母、数字和“$”符号。一切都可以工作(除了用户出于某种原因输入一个空格,所以请提供帮助),但是idk知道我的代码有多高效。我是C的新手,有什么建议吗?(还有什么方法可以为我的密码设置“最大长度”,而不仅仅是将其设置为非常高的值或强制用户遵守限制?)

int main(无效){
int maxlength=15;
字符密码[maxlength];
int指数=0;
int x=0;
int y=0;
int z=0;
printf(“输入密码:”;//迈克$4
scanf(“%s”,密码);
do{//如果索引是strlen,那么我们检查pw的每个字符
//例如,密码长度为6,则将检查索引0-5
如果(索引==strlen(密码)&&x>0&&y>0&&z>0){
printf(“好密码!”);
打破
}
如果(索引==strlen(密码)&(x==0 | | y==0 | | z==0)){
printf(“错误密码”);
打破
}
if(isupper(密码[索引])| | isdigit(密码[索引])||
密码[索引]==“$”){
if(isupper(密码[索引]){
x++;索引++;
继续;}
if(isdigit(密码[索引]){
y++;索引++;
继续;}
如果(密码[索引]=='$'){
z++;索引++;
继续;}
}else{index++;
继续;
}
}while(索引)
我的代码有多高效

编码的一个常见缺陷是关注性能,但C代码中有未定义的行为(UB)。首先修复UB,然后解决效率问题

缓冲区溢出

scanf(“%s”,password);
未提供宽度限制。15个字符或更多字符的密码将通过尝试在
password[]之外写入来调用UB

负片
char

在编码的早期,人们不太可能遇到带有负值的
char
,但是当它们发生时,
is…(int-ch)
函数是一个问题。在这里,
ch
必须在
unsigned char
范围内或
EOF
中有一个值,否则UB再次罢工

// isupper(password[index])
isupper((unsigned char) password[index])

使用UB,考虑<代码> SCANF(“%s”,密码);可以轻松占用您的while循环的时间100x。因此,优化您的代码边界上的微优化。

避免O(n*n)代码

假设密码是length
n
,然后为了找到字符串的长度,需要通过
strlen()
遍历所有
n
字符。代码也在执行
n
循环,每次迭代调用
strlen()
。也就是
n*n
时间

如今,许多编译器会发现
password
在循环中不会更改,因此
strlen(password)
的结果将被记住,从而防止
n*n
迭代

do{
  if(index == strlen(password) && x>0 && y>0 && z>0){
  ...
} while(index <= strlen(password));

不管它值多少钱,你可能想看看最新的。发布一个更有效的代码版本很有诱惑力,但是询问这些建议的正确地方是。至于如何处理空格字符:在任何不允许的字符上,你可以立即打印“坏”字消息和
打破循环。你的学校如何定义“效率?”如果你只是检查一个密码,那么最佳性能几乎不是一个有用的标准。当你用
scanf(“%s”,password)
阅读密码时,你可以保证阅读跳过任何前导空白(包括换行符),然后将在第一个空格字符处停止-空格、制表符或换行符(或其他几个字符之一)。如果要读取一行,请使用
fgets()
,但请记住
fgets()
返回的字符串将包含换行符(通常,除非整行没有足够的空间)。要进行有效的密码输入检查,您可能需要将键盘置于非规范模式,并对每次按键做出响应。这是在输入任何不需要的字符时以及在按下下一个键之前标记该字符的唯一方法。请参阅
do{
  if(index == strlen(password) && x>0 && y>0 && z>0){
  ...
} while(index <= strlen(password));
size_t len = strlen(password);

do {
  // if(index == strlen(password) ...
  if(password[index] != '\0' ...
  // or 
  if(index == len ...

  // }while(index <= strlen(password));
  } while(index <= len);
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#define PWD_N 6

int main(void) {
  size_t maxlength = 15;
  char password[maxlength + 1]; // add 1 for \0
  bool upper = false;
  bool digit = false;
  bool dollar = false;
  bool length_ok = true;

  printf("Enter Password: "); //Mike$4
  fflush(stdout);

  size_t i = 0;
  for (;;) {
    int ch = fgetc(stdin);
    if (ch == '\n' || ch == EOF) {
      break;
    }
    if (i < sizeof password - 1) {
      password[i++] = ch;
      upper |= isupper(ch);
      digit |= isdigit(ch);
      dollar |= ch == '$';
    } else {
      length_ok = false; // too long
    }
  }
  password[i] = '\0';

  if (i == PWD_N && length_ok && upper && digit && dollar) {
    printf("Good password!\n");
  } else {
    printf("BAD PASSWORD\n");
  }
  return 0;
}