C语言登录开发中如何在strcmp内使用OR逻辑匹配数组元素
C语言strcmp多值匹配问题解答
核心疑问直接答复
- 不能在strcmp的参数/数组下标位置直接用
|(按位或)或||(逻辑或)实现“一次匹配多个数组元素”的效果,你代码里的写法是完全错误的。 - 不存在单条字符串比较语句就能遍历匹配数组内所有存储值的写法,
strcmp函数的设计就是每次仅接收两个字符串指针做入参,返回两者的比较结果,要匹配数组内多个元素必须通过循环遍历,或者写多条独立的strcmp判断用逻辑或连接。
你现有代码的错误点
user[0|1|2]的写法完全不符合预期:0|1|2是C语言的按位或运算,会先计算出整数值3(二进制0|1=1,1|2=3),而你的user数组长度为3,有效下标只有0、1、2,访问下标3属于数组越界,会读到栈上的随机垃圾值,根本不可能正确匹配到预置的用户名。- 你使用的
gets()函数是C语言标准正式废弃的高危函数,完全不做输入长度校验,存在缓冲区溢出漏洞,生产环境绝对不能使用,应替换为fgets()。 scanf("%s", &Ipass)写法存在错误:Ipass是字符数组名,传入函数时会自动退化为首元素地址,不需要额外加取地址符&;同时%s格式符默认不限制输入长度,同样存在溢出风险,需要加长度限制。- 现有逻辑没有做用户名和密码的绑定校验:就算正确匹配到用户名,也没有验证对应位置的密码,只要用户名存在就能通过校验,不符合登录逻辑。
修正后的可运行代码
#include <stdio.h> #include <string.h> int main() { int valid_idx = -1; char Iuser[50], Ipass[50]; char user[3][50] = {"user1", "user2", "user3"}; char pass[3][50] = {"pass1", "pass2", "pass3"}; printf("\n Enter your username:"); // 安全读取用户名,限制最大读取长度避免溢出 fgets(Iuser, sizeof(Iuser), stdin); // 清除fgets读取到的末尾换行符 Iuser[strcspn(Iuser, "\n")] = '\0'; // 遍历数组逐一匹配用户名,这是多元素匹配的标准写法 for (int i = 0; i < 3; i++) { if (strcmp(user[i], Iuser) == 0) { valid_idx = i; break; } } if (valid_idx == -1) { printf("\n Invalid Username, Try Again !"); return 0; } printf("\n Enter your password:"); // 限制密码最大读取长度为49,预留字符串结束符位置 scanf("%49s", Ipass); if (strcmp(pass[valid_idx], Ipass) == 0) { printf("\n Login successful!"); } else { printf("\n Invalid Password!"); } return 0; }
额外说明
如果你不想用循环,硬要在一个判断里写完三个用户名的匹配,只能按如下格式写,本质还是三次独立的strcmp调用,用逻辑或连接结果:
if (strcmp(user[0], Iuser) == 0 || strcmp(user[1], Iuser) == 0 || strcmp(user[2], Iuser) == 0) { // 用户名匹配通过逻辑 }
这种写法可维护性极差,当数组内的用户名数量变化时必须手动增减判断条件,实际开发中优先用循环遍历实现。
内容的提问来源于stack exchange,提问作者EJ Navarro
相关产品推荐
相关产品推荐

