程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 用數組實現從文件搜索帳戶和驗證密碼,數組帳戶驗證密碼

用數組實現從文件搜索帳戶和驗證密碼,數組帳戶驗證密碼

編輯:C++入門知識

用數組實現從文件搜索帳戶和驗證密碼,數組帳戶驗證密碼


 

最近一個同學在寫個銀行管理系統,然後問我怎麼從文件搜索帳戶,給了方法後又不懂文件裡面的密碼怎麼與輸入的匹配。一般來說,高效的做法是用鏈表實現。用數組實現不是高效的方法,而且浪費空間。再者,對於賬戶類有個人信息集合的,一般用結構體,代碼寫起來也方便簡單。

但是他卻用數組來做,而且沒有用結構體。對於這種情況下如何搜索帳戶,如何驗證密碼呢? 我嘗試了一下,發現不難解決。

解決這個問題的方法:用文件數據的排序定位來做。

第一步:文件信息讀入

 用fscanf 實現文件讀出文件信息。

1 char a[20];
2 
3 FILE* fp;
4 fp = fopen("test.txt","rb");
5 fscanf (fp, "%s", a);
6 fclose(fp);

fcanf讀取數據,以空格為分割點。比如對於文件內容為“abc ABC”(雙引號之內)的情況,用如下代碼:

 

fscanf (fp, "%s", a);
fscanf (fp, "%s", b);

 

 得到字符數組a 為abc;字符數組b為 ABC;

若文件內容為“abcABC”(雙引號之內)的情況,即abc和ABC之間沒有空格隔開,用以上代碼,得到的結果將是:

字符數組a 為abcABC;字符數組b 為亂碼。

fscanf();還有一個特點,就是在一個程序裡面是順序讀入的。

在此舉個例子:

txt文件(每個數據一行)內容:

abc

ABC

ruby

 

然後執行下面的代碼:

int main()
{
  char a[20],b[20],c[20];
  FILE* fp;
  fp = fopen("test.txt","rb");
  fscanf(fp, "%s", a);
  //……此處省略n行代碼
  fscanf(fp, "%s",b);
  //……此處省略n行代碼
 fscanf(fp, "%s",c);
 fclose(fp);
return 0;
}

 

 得到的結果是:

字符數組a為 abc,b為ABC,c為ruby;

 

第二步:搜索賬號

 

 

賬號搜索的方法是遍歷文件數據,找到與輸入匹配的賬號就停止搜索。

用 while(fscanf(fp,"%s",a) > 0) 實現遍歷文件數據。

作用是把文件內容一行一行讀入賦值給字符數組a,然後再與輸入的賬號進行比較。

同時使用標記 flag 判斷是否找到匹配的賬號,以便後續處理各種不同情況。

代碼如下:

 

 

char a[20];
char shuRu[20] = {'\0'}; //輸入

int flag = 0;

cout << "請輸入賬號名: ";
cin >> shuRu;

FILE* fp;
fp = fopen("test.txt","rb");

while(fscanf(fp,"%s",a) > 0) //遍歷文件數據
{
    if (strcmp(shuRu,a) == 0)
    {
                cout << "找到匹配賬號" << endl;
        flag = 1;
                break;
        }
}

if (flag == 0){
  cout << "用戶不存在,請注冊!" << endl;
  //下一步
}
else
  //下一步;
fclose(fp);

 

 代碼中判斷數據相同用strcmp(str1,str2); 如果兩個字符數組存儲的內容相同,則 strcmp(str1,str2)== 0

此時停止搜索,用break;跳出循環。

現在舉例一下:

其中第三行為賬號,第五行為密碼。其他的為姓名,地址,年齡等其他信息。

運行如下:

 

 第三步:定位文件密碼數據

如果是用結構體,當檢測到帳號的時候,再用結構體的 “.” 也就是 “點”密碼 來解決。簡單方便。但是用的不是結構體,所以只能用其他方法。隨筆開頭寫了用“排序定位”來做,如何實現?

從這個文件數據來看,賬號與密碼分別是第三行, 第五行,中間隔了個第四行。下面另一個帳戶也是同樣的排序。

那麼就定位到第五行,然後再進行 輸入密碼 與 文件數據的比較。

代碼如下:

 

if (strcmp(shuRu,a) == 0)
{
    flag = 1;
    fscanf(fp,"%s",a);
    fscanf(fp,"%s",a);
    break;
}

 

 這裡面當檢測到帳號的時 flag = 1;表示找到匹配賬號。

然後用了 兩個fscanf(fp,"%s",a); 這不是代碼錯誤,前面提到了fscanf(); 是順序讀入,並且舉了 a,b,c三個字符數組的例子。

這裡再說明一下為何用兩個fscanf();

第一個fscanf();是把賬號下面的第一個數據賦值給了 字符數組a;

第二個fscanf();是把賬號下面的第二個數據賦值給了 字符數組a;

由於密碼數據是賬號數據下面的第二個數據,所以必須用兩個fscanf(); 因為fscanf();為順序讀入,無法進行跳躍。

 

第四步:驗證密碼  

定位了密碼數據,那麼就可以進行密碼驗證了。為了實現當密碼輸入錯誤時,能重新輸入,我們必須把驗證密碼這個環節寫成一個函數,然後自身循環調用,類似遞歸的用法。

代碼如下:

 

void checkKey(char a[20])
{
    char mima[20];
    cout << "輸入密碼:";
    cin >> mima;
    if (strcmp(a, mima) == 0)
        cout << "登錄成功" << endl;
    else
    {
        cout << "密碼輸入錯誤!請重新輸入。" << endl;
        Sleep(2000);
        checkKey(a);
    }

    return;
}

 

 

 第五步:demo運行

初步完成了這個功能,現在把完整代碼貼出來。

 

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <windows.h>
 5 using namespace std;
 6 
 7 //檢測密碼
 8 void checkKey(char a[20])
 9 {
10     char mima[20];
11     cout << "輸入密碼:";
12     cin >> mima;
13     if (strcmp(a, mima) == 0)
14         cout << "登錄成功" << endl;
15     else
16     {
17         cout << "密碼輸入錯誤!請重新輸入。" << endl;
18         Sleep(2000);
19         checkKey(a);
20     }
21 
22     return;
23 }
24 
25 int main()
26 {
27     char a[20];
28     char shuRu[20] = {'\0'};
29 
30     int flag = 0;
31 
32     cout << "請輸入賬號名: ";
33     cin >> shuRu;
34 
35     FILE* fp;
36     fp = fopen("test.txt","rb");
37 
38     while(fscanf(fp,"%s",a) > 0)
39     {
40 
41         if (strcmp(shuRu,a) == 0)
42         {
43             flag = 1;
44             fscanf(fp,"%s",a);
45             fscanf(fp,"%s",a);
46             break;
47 
48         }
49         
50     }
51     if (flag == 0)
52         cout << "用戶不存在,請注冊!" << endl;
53     else
54         checkKey(a);
55 
56     fclose(fp);
57     return 0;
58 }

 

我們來運行一下。

首先文件數據如下:(每個帳戶的第三行為帳號,第五行為密碼)

運行結果:

 

第六步:bug修復 

看上去好像完成了相應預期功能,但是細心觀察,不難發現一個bug。舉例說明一下:

當文件內容為:

可以看出,第一個帳戶的密碼和第二個帳戶的賬號相同,都是aabbcc,此時程序運行就有錯誤,當搜索到了aabbcc,程序就把他當成了賬號,於是出錯。

修復bug也很簡單,用一種特殊字符對賬號進行處理。比如在賬號後面追加一個 “@”。

因此,程序要修改兩個地方

1. 帳戶注冊後把信息寫入文件時,在賬號後面追加一個 “@”

2. 登錄時,當輸入賬號完畢後,也給輸入的賬號後面追加一個“@”

第一個地方不是我們討論的范圍,我們來看看與本篇隨筆有關的要修改的第二個地方:

相關函數: strcat(str1,str2);實現把字符數組 str2 追加到 str1 後面。

代碼如下:

 

cout << "請輸入賬號名: ";
cin >> shuRu;
strcat(shuRu,"@");

 

 所以,當你登錄時,輸入賬號完成按回車鍵時,程序會自動給你輸入的賬號後面追加一個字符”@“,然後再與文件數據進行比較。

修改後的完整代碼如下:

 

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <windows.h>
 5 using namespace std;
 6 
 7 //檢測密碼
 8 void checkKey(char a[20])
 9 {
10     char mima[20];
11     cout << "輸入密碼:";
12     cin >> mima;
13     if (strcmp(a, mima) == 0)
14         cout << "登錄成功" << endl;
15     else
16     {
17         cout << "密碼輸入錯誤!請重新輸入。" << endl;
18         Sleep(2000);
19         checkKey(a);
20     }
21 
22     return;
23 }
24 
25 int main()
26 {
27     char a[20];
28     char shuRu[20] = {'\0'};
29 
30     int flag = 0;
31 
32     cout << "請輸入賬號名: ";
33     cin >> shuRu;
34     strcat(shuRu,"@");
35 
36     FILE* fp;
37     fp = fopen("test.txt","rb");
38 
39     while(fscanf(fp,"%s",a) > 0)
40     {
41 
42         if (strcmp(shuRu,a) == 0)
43         {
44             flag = 1;
45             fscanf(fp,"%s",a);
46             fscanf(fp,"%s",a);
47             break;
48 
49         }
50         
51     }
52     if (flag == 0)
53         cout << "用戶不存在,請注冊!" << endl;
54         
55     else
56         checkKey(a);
57 
58     fclose(fp);
59     return 0;
60 }

 

 文件數據:

運行結果:

密碼匹配成功。

總結:對於沒有用鏈表 + 結構體的來寫帳戶登記的程序,屬於純文件信息處理。那麼就只能差強人意的用一些方法來解決。用的是”排序定位“的方法。

代碼是追求高效,簡潔的。一開始沒有用好的方法去解決,雖然也能通向羅馬,從程序的維護和更新的角度來看,是不推薦的。

 


怎使用asp遍歷數組 實現單用戶多密碼登陸

1樓的 好像沒讀懂題目..

設:拿到的帳號變量為 u 密碼變量為 p

....
sql = "select user,pass from admin where user='" & u & "'"
set rs = conn.execute(sql)

if rs.eof then
response.write("找不到該用戶!")
response.end
end if

dim check,arr
check = false
arr = split(rs("pass"),"|")
for i = 0 to ubound(arr)
if p=arr(i) then
check = true
exit for
end if
next

if not check then
response.write("密碼錯誤")
response.end
end if

'這裡就是 帳號密碼都通過後執行的........
 

java 用數組的方式接收用戶輸入的數 並輸出數組 怎實現?

public class Util{ public static void main(String[] args){ java.util.Scanner sc = new java.util.Scanner(System.in); String[] arr = new String[5]; for(int i = 0; i < arr.length; i++){ arr[i] = sc.next(); } //這裡使用util.Arrays的代碼輸出數組 System.out.println(java.util.Arrays.toString(arr)); }}
孫成 [權威專家]

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved