[英]Using OR in statements with arrays, (C)
我一直在嘗試創建一個用戶名和密碼界面,我想知道是否可以在strcmp
中有一個 or 語句,以及我是否也可以在 1 個字符串中使用數組的所有值,謝謝!
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
int main(int argc, char *argv[]) {
int u, p;
char Iuser[50],Ipass[50];
char user[3][50] = { "user1", "user2", "user3" };
char pass[3][50] = { "pass1", "pass2", "pass3" };
printf("\n Enter your username:");
gets(Iuser);
u = strcmp(user[0|1|2], Iuser);
if (u == 0) {
printf("\n Enter your password");
scanf("%s", &Ipass);
} else {
printf("\n Invalid Username, Try Again !");
}
}
不,你不能在 C 中那樣做。
我正在竊取 Aconcagua 關於其實際功能的評論:
user[0|1|2]
首先計算0|1|2
,然后訪問數組。 但是,按位 OR-ing 0、1 和 2 的結果是 3,這已經超出了user
數組的范圍,因此行為未定義
所以,而不是
u=strcmp(user[0|1|2],Iuser);
if(u==0) {
你應該做:
#include <stdbool.h>
bool u = strcmp(user[0], Iuser) == 0 ||
strcmp(user[1], Iuser) == 0 ||
strcmp(user[2], Iuser) == 0;
if(u) {
如果用戶數組很長或在編譯時不知道用戶數:
bool u = false;
for(int i = 0; i < number_of_users; ++i) {
if(strcmp(user[i], Iuser) == 0) {
u = true;
break;
}
}
if(u) {
注意:不要使用按位OR
, |
, 對於這些比較。 使用邏輯OR
, ||
, 啟用短路評估,以便它在一個條件為true
時立即停止測試,就像上面的循環一旦發現一個條件為true
就break
。
你應該做
u=strcmp(user[0],Iuser)!=0 && strcmp(user[1], Iuser)!=0 && strcmp(user[2],Iuser)!=0;
if(u==0) {
//User exists so ask password
因為 strcmp 只接受兩個字符串進行比較。 如果您按照您所說的那樣進行 OR,這將是一些奇怪的事情,例如 char 數組中的按位運算,我懷疑它是否會編譯,我們不想這樣做。
祝你有美好的一天。
strcmp
不能以這種方式使用: user[0|1|2]
計算結果為user[3]
,它訪問數組末尾之外的數組元素: strcmp()
從該位置讀取時將具有未定義的行為。
C 庫沒有用於在數組中定位字符串的通用函數,因此您應該編寫:
u = strcmp(user[0], Iuser) && strcmp(user[1], Iuser) && strcmp(user[2], Iuser);
這是非常詳細和具體的。
請注意,您應始終要求輸入密碼以避免將有關用戶名的信息提供給入侵者,因此應將代碼修改為:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char Iuser[50];
char Ipass[50];
char user[3][50] = { "user1", "user2", "user3" };
char pass[3][50] = { "pass1", "pass2", "pass3" };
int nusers = sizeof(user) / sizeof(user[0]); // number of users
int u;
for (;;) {
printf("\n Enter your username:");
if (scanf("%49s", Iuser) != 1)
return 1;
printf("\n Enter your password");
if (scanf("%49s", Ipass) != 1)
return 1;
for (u = 0; u < nusers; u++) {
if (strcmp(user[u], Iuser) == 0 && strcmp(pass[u], Ipass) == 0)
break;
}
if (u < nusers)
break;
printf("\n Invalid Username and/or password, Try Again !");
}
// user has been authenticated.
// ...
return 0;
}
另請注意,應在不將字符回顯到終端的情況下讀取密碼,這很棘手,但可以通過getpass
在 unix 系統上實現:
#include <pwd.h>
#include <unistd.h>
char *getpass(const char *prompt);
密碼不應像您那樣以明文形式存儲,也不應以加密文本形式存儲,因為它們太容易找到。 除了更高級的技術外,還建議計算加密哈希。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.