#include<stdio.h>
#include<string.h>
#include<windows.h>
#define bool char
#define true 1
#define false 0
#define NUM 100
// IC卡賬戶信息
struct cardInfo
{
char sno[20]; // 學號
char name[20]; // 姓名
char cardID[12]; // 卡號
float balance; // 餘額
};
// 函數聲明
bool login();
void menu(); // 主菜單
void openAccount(); // 開戶
void showCardInfo(struct cardInfo card); // 顯示賬戶信息的方法
void showCardInfos(struct cardInfo cards[], int count);
void view(); // 顯示所有賬戶信息
void income(); // 充值
void init(); // 初始化
void saveData(); // 保存數據
void search(); // 查找
struct cardInfo cards[NUM]; // 用來存放所有的賬戶信息
int TOTALCOUNT = 0; // 記錄數
bool isEnd = false; // 是否退出系統
void main()
{
bool bl = 0;
int count = 0; // 用戶記錄輸入輸入賬號和密碼的次數,最多允許輸入3次
do
{
if (count == 3)
{
break; // 跳出while循環
}
if (count > 0)
{ // 說明不是第一次登陸
printf("\n\n\t賬號或密碼錯誤,請確認後重新登錄...");
printf("\n\n\t您還有 %d 次機會<請按回車繼續>", 3-count);
getch();
}
count++;
bl = login(); // 調用登陸的方法,實現用戶登陸
}while( !bl );
// 問題:當用戶登陸成功也會跳出while,如果超過3次也會跳出while
if ( !bl )
{
printf("\n\n\t對不起,您暫無權限...\n\t");
system("exit");
} else // 登陸成功
{
init(); // 初始化數據,即將數據從數據文件讀取到系統中
do{
menu(); // 顯示主菜單
}while(!isEnd);
}
printf("\n\n\t");
exit;
system("exit /B");
}
// 主菜單
void menu()
{
int flag = 0 ;
system("cls");
printf("\n\t**********************湖南工學院IC卡管理系統**********************");
printf("\n\t************************** 1. IC卡開戶 **************************");
printf("\n\t************************** 2. 查詢IC卡信息 ***********************");
printf("\n\t************************** 3. 瀏覽IC卡信息 ***********************");
printf("\n\t************************** 4. IC卡充值 ************************");
printf("\n\t************************** 5. 修改IC卡信息 ***********************");
printf("\n\t************************** 6. 退出系統 ************************");
printf("\n\n\t請選擇您要進行的操作(1-6):");
scanf("%d",&flag);
switch(flag)
{
case 1:openAccount(); break;
case 2:search(); break;
case 3:view(); break;
case 4:income(); break;
case 5: break;
case 6:saveData(); isEnd=true; break;
default:break;
}
}
// 用戶登錄方法
bool login()
{
char name[20]; // 存儲用戶輸入的賬號
char pwd[20], ch; // 存儲用戶輸入的密碼
int index = 0; // 輸入密碼的位數
system("cls");
printf("\n\t**********************湖南工學院IC卡管理系統**********************");
printf("\n\n\t請輸入您的賬號:");
// 獲取用戶輸入的賬號
scanf("%s", name);
printf("\n\t請輸入您的密碼:");
// 獲取用戶輸入的密碼
while ( (ch=getch()) != 13 ) // 不是回車鍵
{
if ( ch ==8 ) // 如果是退格 Backspace
{
if(index <= 0)
{
index = 0;
}
else
{
printf("\b \b");
index --;
}
}
else
{
pwd[index++] = ch;
putch('*');
}
}
pwd[index] = '\0';
//scanf("%s", pwd); // 當用戶輸入密碼時,如何用掩碼的方式顯示 ***
// 比較用戶輸入的賬號和密碼是否正確。如果用戶輸入的賬號是yc 並且密碼是 123321,則認爲是合法的用戶,那麼跳轉到主界面,否則提示錯誤。
if ( strcmp("yc",name) == 0 && strcmp("123321", pwd) == 0)
{
return true;
} else
{
return false;
}
}
// 開戶
void openAccount()
{
struct cardInfo card; // 聲明結構體變量
int result;
FILE *fp; // 聲明一個文件指針,用來指向打開的這個文件
system("cls");
printf("\n\t**********************湖南工學院IC卡管理系統**********************");
printf("\n\t************************** IC卡開戶 **************************");
printf("\n\t*********************** 請輸入以下信息 ************************");
printf("\n\n\t請輸入學號:");
scanf("%s", card.sno);
printf("\n\t請輸入卡號:");
scanf("%s", card.cardID);
printf("\n\t請輸入姓名:");
scanf("%s", card.name);
printf("\n\t請輸入充值金額:");
scanf("%f", &card.balance);
printf("\n\n\t您輸入的信息爲:");
showCardInfo(card);
result = MessageBox(NULL, "您確定要添加此賬號信息嗎?", "確認提示", MB_YESNO|MB_ICONINFORMATION);
if (result == 6) // 說明確定添加
{
strcpy(cards[TOTALCOUNT-1].sno, card.sno);
strcpy(cards[TOTALCOUNT-1].cardID, card.cardID);
strcpy(cards[TOTALCOUNT-1].name, card.name);
cards[TOTALCOUNT-1].balance = card.balance;
TOTALCOUNT++;
// 將這個數據寫入到數據文件
/*
打開一個數據文件
fopen(要打開的數據文件路徑, 打開的方式);
*/
fp = fopen("cards.txt","a"); // 以追加的方式打開文件
/*
將要保存的數據寫入到這個打開的文件中
fwrite() 寫入數據到指定文件中,它裏面包含四個參數
第一個參數:要寫入數據文件的數據的地址 -> 要將用戶輸入的這個IC卡賬號信息寫入到數據文件 -> 即這個賬號結構體的地址
第二個參數:要寫入數據文件的數據的大小 -> 要將這個結構體數據寫入到數據文件,所以我要寫入的數據文件大小應該就是這個結構體大小
第三個參數:要寫入幾個這個的大小 -> 這裏我們只需要保存一個IC卡賬戶信息
第四個參數:寫入到那個數據文件 -> 這裏是寫入到我們打開的這個數據文件fp
*/
fwrite(&card, sizeof(struct cardInfo), 1, fp);
// 關閉文件
fclose(fp);
printf("\n\n\t卡戶成功<請按回車鍵返回>\n\n\t");
}
else
{
printf("\n\n\t不添加\n\n\t");
}
}
// 用來顯示指定的賬戶信息
void showCardInfo(struct cardInfo card)
{
printf("\n\n\t 卡號 \t\t 學號 \t\t學生姓名 \t\t 餘額 ");
printf("\n\t%-15s\t%-12s\t%-20s\t%-6.2f\t",card.cardID,card.sno,card.name,card.balance);
printf("\n\n\t");
}
// 瀏覽賬戶信息
void view()
{
system("cls");
printf("\n\t**********************湖南工學院IC卡管理系統**********************");
printf("\n\t************************ 瀏覽賬戶信息 ************************");
if (TOTALCOUNT>0)
{
// 顯示數據
showCardInfos(cards, TOTALCOUNT);
printf("\n\n\t<請按回車返回>");
}
else
{
printf("\n\n\t暫無賬號信息<請按回車返回>");
}
getch();
}
// 顯示單個賬戶信息
void showCardInfos(struct cardInfo cards[], int count)
{
int i = 0;
printf("\n\n\t 卡號 \t\t 學號 \t\t學生姓名 \t\t 餘額 ");
for(i; i<count-1; i++)
{
printf("\n\t%-15s\t%-12s\t%-20s\t%-6.2f\t", cards[i].cardID, cards[i].sno, cards[i].name, cards[i].balance);
}
printf("\n\n\n\t************************ 共 %d 條數據 ************************", count-1);
printf("\n\n\t");
}
// 初始化系統,用來讀取本系統中的數據所有數據
void init()
{
FILE *fp;
if ( (fp = fopen("cards.txt", "r") ) != NULL)
{
// 循環讀取數據到結構體數組中
while( !feof(fp) ) // feof file end of: 到文件最後了嗎
{
/*
fread() 用來從指定的數據文件讀取數據
第一個參數:將數據讀到哪裏 -> 將數據從數據文件讀到結構體數據中
第二個參數:每個讀多大 -> 每次讀取一個結構體那麼大
第三個參數:每次讀幾個這樣的大小
第四個參數:從哪裏讀 -> 從打開的數據文件中讀
*/
fread(&cards[TOTALCOUNT], sizeof(struct cardInfo), 1, fp);
TOTALCOUNT++;
}
fclose(fp);
}
}
// 充值
void income()
{
char cardID[12]; // 用來存放用戶輸入的充值卡卡號
int i = 0;
float money;
system("cls");
printf("\n\t**********************湖南工學院IC卡管理系統**********************");
printf("\n\t************************ 賬戶充值中心 ************************");
// 先判斷系統中有沒有用戶信息
if (TOTALCOUNT > 0) {
printf("\n\n\t請輸入要充值的卡號:");
scanf("%s", cardID);
// 從系統中查找有沒有這個卡號
for (i=0; i<TOTALCOUNT-1; i++)
{
if (strcmp(cardID, cards[i].cardID) == 0)
{ // 如果是相等的,則說明這個用戶找到了
// 顯示這個賬號,然後提醒輸入輸入充值的金額
printf("\n\n\t您要充值的賬戶信息如下:");
showCardInfo(cards[i]);
printf("\n\n\t請輸入充值金額:");
scanf("%f", &money);
// 修改此賬戶的餘額
cards[i].balance += money;
// 將數據寫入到數據文件
printf("\n\n\t充值成功<請按回車鍵返回>");
break;
}
}
// 第一種是找到了退出循環,第二種是沒找到退出循環
if ( i >= TOTALCOUNT-1 )
{
printf("\n\n\t暫無該賬號信息<請按回車返回>");
}
}
else
{
printf("\n\n\t暫無賬號信息<請按回車返回>");
}
getch();
}
// 保存數據
void saveData()
{
FILE *fp;
int i = 0;
if (TOTALCOUNT > 0) { // 說明有數據要保存
fp = fopen("cards.txt","w"); // 以追加的方式打開文件
/*
將要保存的數據寫入到這個打開的文件中
fwrite() 寫入數據到指定文件中,它裏面包含四個參數
第一個參數:要寫入數據文件的數據的地址 -> 要將用戶輸入的這個IC卡賬號信息寫入到數據文件 -> 即這個賬號結構體的地址
第二個參數:要寫入數據文件的數據的大小 -> 要將這個結構體數據寫入到數據文件,所以我要寫入的數據文件大小應該就是這個結構體大小
第三個參數:要寫入幾個這個的大小 -> 這裏我們只需要保存一個IC卡賬戶信息
第四個參數:寫入到那個數據文件 -> 這裏是寫入到我們打開的這個數據文件fp
*/
for(i=0; i<TOTALCOUNT-1; i++)
{
fwrite(&cards[i], sizeof(struct cardInfo), 1, fp);
}
// 關閉文件
fclose(fp);
}
else
{
remove("cards.txt");
}
}
// 查找
void search()
{
char sno[20]; // 用來存放用戶輸入的充值卡卡號
int i=0, index = 0, len = 0, count = 0;
bool isFind = false; // 是否找到
struct cardInfo cd[NUM]; // 滿足條件的賬戶信息
system("cls");
printf("\n\t**********************湖南工學院IC卡管理系統**********************");
printf("\n\t************************ 賬戶查詢中心 ************************");
// 先判斷系統中有沒有用戶信息
if (TOTALCOUNT > 0) {
printf("\n\n\t請輸入要查詢的學生學號:");
scanf("%s", sno);
// 從系統中查找有沒有這個卡號
for (i=0; i<TOTALCOUNT-1; i++) // 模糊查找
{
isFind = true;
for(index=0,len=(int)strlen(sno); index<len; index++)
{
if(cards[i].sno[index] != sno[index] ) // 說明不匹配
{
isFind = false;
break;
}
}
// 如果所有的字符都能匹配則滿足條件
if (isFind)
{
cd[count] = cards[i];
count++;
}
}
// 第一種是找到了退出循環,第二種是沒找到退出循環
if ( count > 0)
{
printf("\n\n\t滿足條件的信息如下:");
showCardInfos(cd, count+1);
}
else
{
printf("\n\n\t暫無該賬號信息<請按回車返回>");
}
}
else
{
printf("\n\n\t暫無賬號信息<請按回車返回>");
}
getch();
}