簡體   English   中英

在帶有數組的語句中使用 OR,(C)

[英]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時立即停止測試,就像上面的循環一旦發現一個條件為truebreak

你應該做

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM