用陣列實現從檔案搜尋帳戶和驗證密碼

2021-12-29 20:33:58 字數 4732 閱讀 5037

最近乙個同學在寫個銀行管理系統,然後問我怎麼從檔案搜尋帳戶,給了方法後又不懂檔案裡面的密碼怎麼與輸入的匹配。一般來說,高效的做法是用鍊錶實現。用陣列實現不是高效的方法,而且浪費空間。再者,對於賬戶類有個人資訊集合的,一般用結構體,**寫起來也方便簡單。

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

解決這個問題的方法:用檔案資料的排序定位來做。

第一步:檔案資訊讀入

用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檔案(每個資料一行)內容:

abcabc

ruby  

然後執行下面的**:

複製**

int main()

複製**  

得到的結果是:

字元陣列a為 abc,b為abc,c為ruby;  

第二步:搜尋賬號  

賬號搜尋的方法是遍歷檔案資料,找到與輸入匹配的賬號就停止搜尋。

用 while(fscanf(fp,"%s",a) > 0) 實現遍歷檔案資料。

作用是把檔案內容一行一行讀入賦值給字元陣列a,然後再與輸入的賬號進行比較。

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

**如下:  

複製**

char a[20];

char shuru[20] = ; //輸入

int flag = 0;

cout << "請輸入賬號名: ";

cin >> shuru;

file* fp;

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

while(fscanf(fp,"%s",a) > 0) //遍歷檔案資料} 

if (flag == 0)

else

//下一步;

fclose(fp);

複製**  

**中判斷資料相同用strcmp(str1,str2); 如果兩個字元陣列儲存的內容相同,則 strcmp(str1,str2)== 0

此時停止搜尋,用break;跳出迴圈。

現在舉例一下:  

其中第三行為賬號,第五行為密碼。其他的為姓名,位址,年齡等其他資訊。

執行如下:  

第三步:定位檔案密碼資料

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

從這個檔案資料來看,賬號與密碼分別是第三行, 第五行,中間隔了個第四行。下面另乙個帳戶也是同樣的排序。

那麼就定位到第五行,然後再進行 輸入密碼 與 檔案資料的比較。

**如下:  

複製**

if (strcmp(shuru,a) == 0)

複製**  

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

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

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

第乙個fscanf();是把賬號下面的第乙個資料賦值給了 字元陣列a;

第二個fscanf();是把賬號下面的第二個資料賦值給了 字元陣列a;

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

第四步:驗證密碼  

定位了密碼資料,那麼就可以進行密碼驗證了。為了實現當密碼輸入錯誤時,能重新輸入,我們必須把驗證密碼這個環節寫成乙個函式,然後自身迴圈呼叫,類似遞迴的用法。

**如下:  

複製**

void checkkey(char a[20])

return;

}複製**  

第五步:demo執行

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

複製**

1 #include

2 #include

3 #include

4 #include

5 using namespace std;

6  7 //檢測密碼

8 void checkkey(char a[20])

9 21 

22     return;

23 }

24 25 int main()

26 ;

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    

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

2 #include

3 #include

4 #include

5 using namespace std;

6  7 //檢測密碼

8 void checkkey(char a[20])

9 21 

22     return;

23 }

24 25 int main()

26 ;

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    

50         

51     }

52     if (flag == 0)

53         cout << "使用者不存在,請註冊!" << endl;

54         

55     else

56         checkkey(a);

57 58     fclose(fp);

59     return 0;

60 }

複製**  

密碼匹配成功。

總結:對於沒有用鍊錶 + 結構體的來寫帳戶登記的程式,屬於純檔案資訊處理。那麼就只能差強人意的用一些方法來解決。用的是」排序定位「的方法。

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

用陣列和鍊錶實現棧

完成乙個棧總共需要完成以下操作 初始化入棧 出棧檢視棧頂元素 檢視棧的容量 清空棧。首先是簡單的,用陣列做的,會有越界的可能。include include typedef struct stack stack stack s 生成棧 void initstack 入棧,push void push...

用C 實現pdf檔案的完整性驗證

現在對檔案的完整性驗證,防止檔案被篡改的技術已經比較成熟,一般使用數字簽名,數字水印等,最近我在乙個專案中也遇到了防篡改的需求。該專案要求使用者將原始發票用專門的掃瞄程式掃瞄成pdf檔案,然後將該pdf檔案傳到伺服器上,在上傳的同時必須要驗證這個pdf是沒有被手工修改過的。我剛一接觸到這個需求想到的...

用JS實現簡單敏感詞過濾和表單驗證

首先完成html輸入框 10 cols 30 name id txt1 textarea button onclick btnclick 發布 button msg div body css text css msg style 事件驅動函式 function btnclick omsg.inner...