题目描述
给定用户密码输入流 input,输入流中字符’<'表示退格,可以清除前一个输入的字符,请你编写程序,输出最终得到的密码字符,并判断密码是否满足如下的密码安全要求。
密码安全要求如下:
密码长度>=8;
密码至少需要包含 1 个大写字母;
密码至少需要包含 1 个小写字母;
密码至少需要包含 1 个数字;
密码至少需要包含 1 个字母和数字以外的非空白特殊字符
注意空串退格后仍然为空串,且用户输入的字符串不包含‘<’字符和空白字符。
输入描述
用一行字符串表示输入的用户数据,输入的字符串中‘<’字符标识退格,用户输入的字符串不包含空白字符,例如:ABC<c89%000<
输出描述
输出经过程序处理后,输出的实际密码字符串,并输出改密码字符串是否满足密码安全要求。两者间由‘,’分隔, 例如:ABc89%00,true
示例一
输入
ABC<c89%000<
1
输出
ABc89%00,true
1
说明
解释:多余的 C 和 0 由于退格被去除,最终用户输入的密码为 ABc89%00,且满足密码安全要求,输出 true
代码
//密码输入检测 #include<stdio.h> #include<ctype.h>//提供字符分类函数,如 isupper 和 isdigit。 #include <string.h> #include <stdlib.h> #include<stdbool.h> //接受字符数组 input_stream 作为输入,表示带有潜在退格符的密码。 char *process(char *ch){ //char* 表示指向字符(char)类型的指针,这里的 process_password 函数定义接受一个指向字符数组(即字符串)的指针作为参数。 //函数返回值前面的星号同样表明它返回的是一个指向字符的指针,也就是一个字符串。 char stack[1000];//使用堆栈来处理密码 int top=0; for(int i=0;ch[i]!='\0';++i){ char cur=ch[i]; //将字符压入堆栈,但退格符 (<) 会删除前一个字符。 if(cur=='<'){ if(top>0){ top--; } } else{ stack[top]=cur; top++; } } //返回包含已处理密码的新字符数组。 char *password=malloc(top+1); for(int i=0;i<top;++i){ password[i]=stack[i]; } password[top]='\0'; return password; } //检查密码安全要求 int check(char *password){ int length_check=strlen(password)>=8;//密码长度>=8; int uppercase_check=0; int lowercase_check=0; int digit_check=0; int special_char_check=0; for(int i=0;password[i]!='\0';++i){ if(isupper(password[i])) uppercase_check=1;//密码至少需要包含 1 个大写字母; else if(islower(password[i])) lowercase_check=1;//密码至少需要包含 1 个小写字母; else if(isdigit(password[i])) digit_check=1;//密码至少需要包含 1 个数字; else if(!isalnum(password[i]) && !isspace(password[i])) special_char_check=1; } return length_check && uppercase_check && lowercase_check && digit_check && special_char_check; } int main(){ char ch[1000]; fgets(ch,sizeof(ch),stdin); ch[strcspn(ch,"\n")]='\0';//去除 input_stream 字符串末尾的换行符(\n)。 //strcspn(input_stream, "\n") 用来指示位置 //当 \n 出现在双引号 " 内时,它是一个有效的转义序列 // '\n'和"\n"有 区别,'\0'和"\0"没有区别 char *password=process(ch); bool is_valid=false; if(check(password)){ is_valid=true; } printf("%s,%d\n",password,is_valid); free(password); return 0; }
解释
头文件
stdio.h
:提供标准输入输出函数,如printf
和fgets
。ctype.h
:提供字符分类函数,如isupper
和isdigit
。函数
process(char* input_stream)
:
- 接受字符数组
input_stream
作为输入,表示带有潜在退格符的密码。- 使用堆栈来处理密码:
- 将字符压入堆栈,但退格符 (
<
) 会删除前一个字符。
- 返回包含已处理密码的新字符数组。
check(char* password)
:
- 接受密码作为输入。
- 检查是否满足某些要求:
- 长度至少为 8 个字符。
- 包含至少一个大写字母、一个小写字母、一个数字和一个特殊字符。
- 如果密码满足所有要求,返回 1,否则返回 0。
主函数(main)
- 读取输入:
- 使用
fgets
从用户读取一行输入并将其存储在input_stream
中。- 使用
strcspn
从输入中删除任何换行符 (\n
)。
- 处理密码:
- 调用
process
来删除退格符并获取实际密码。
- 检查密码要求:
- 调用
check
来确定密码是否符合标准。
- 打印输出:
- 打印已处理的密码和一个 1 或 0 来指示其是否有效。
- 释放内存:
- 使用
free
释放用于处理密码的动态分配内存。总结
该代码有效地处理带有退格符的密码输入,并根据特定要求检查其是否有效,然后打印处理后的密码及其有效性状态。
以下是一些具体的解释:
process()
函数使用一个堆栈来处理密码。当遇到一个字符时,如果该字符不是退格符,则将其压入堆栈。如果该字符是退格符,则将堆栈中的顶部字符弹出。这意味着在处理完成后,堆栈中只包含密码中的有效字符。check()
函数检查密码是否符合以下要求:
- 长度至少为 8 个字符。
- 包含至少一个大写字母、一个小写字母、一个数字和一个特殊字符。
- 特殊字符是指除了字母和数字之外的任何字符。
- 主函数首先使用
fgets()
从用户读取一行输入。然后,它使用strcspn()
从输入中删除任何换行符。接下来,它调用process()
来处理密码。然后,它调用check()
来检查密码是否符合要求。最后,它打印密码及其有效性状态。