活期儲蓄帳目管理系統
【問題描述】
編寫一個活期儲蓄帳目管理系統,實現儲戶開戶、銷戶、存入、支出等活動。其主要要求是能比較迅速地找到儲戶的帳戶,實現存款、取款,還要能比較簡單、迅速地實現插入和刪除,以實現開戶和銷戶的需要。
【基本要求】
(1)實現儲戶開戶。開戶時需要填寫登記卡,記錄儲戶信息(包括姓名和帳號),並設置開戶餘額爲0。
(2)實現儲戶銷戶。需要先找到儲戶的帳戶信息,然後將其刪除。
(3)向某帳戶存款。
(4)從某帳戶取款。
(5)排序顯示所有帳戶信息。根據帳號對所有帳戶信息排序。
(6)查詢某帳戶餘額。
【選作內容】
(1)查詢某帳戶交易記錄。
(2)所有帳戶及其交易信息存儲至文件,程序運行時從文件中讀入。
理清頭緒, 再加上一些些簡單的庫函數調用就OK了。
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#include <time.h>
#define USERS_FILENAME "Users_information.txt"
#define RECORDOPERATION_FILENAME "Record_operation.txt"
#define Status int
#define ERROR 1
#define OK 0
#define OVERFLOW -1
typedef struct {
//該類型結構體用於記錄賬戶信息
char name[10]; //用戶姓名
double number; //用戶賬號
int balance; //賬號餘額
} Account;
typedef struct LNode {
//用鏈表存儲賬戶信息
Account data; //鏈表指針域爲賬戶信息
struct LNode *next; //指針域
} LNode, *LinkList;
typedef struct {
//該結構體用於記錄賬號的操作記錄
int time_year;
int time_mon;
int time_day;
int time_hour;
int time_min;
int time_sec;
double record_accont;
char record_name [6];
int money_number;
} Record;
typedef struct Operation {
//該鏈表存儲操作記錄
Record data;
struct Operation *next;
} Operation, *RecordOperation;
Status Read_Account ( LinkList &L ) {
//從文件讀入數據並初始化賬號信息鏈表
LinkList p,q;
FILE *fp = fopen ( USERS_FILENAME, "r" ); //以只讀的方式打開存有用戶信息的文件
if ( !fp )
{
printf ("\n用戶信息文件不存在\n");
FILE *fp = fopen ( USERS_FILENAME, "wa" );
printf ( "\n\n新建用戶信息文件成功\n\n" );
}
L = ( LinkList ) malloc (sizeof (LNode) ); //構建鏈表
if ( !L )
{
printf ("\n分配內存失敗\n");
exit ( ERROR );
}
L->next = NULL;
if ( !fread ( &L->data, sizeof( Account ), 1, fp ) )
{
//當讀入文件得到無效信息時
L->data.number = 20175101000; //第一個註冊的賬號以 20175101000 爲基礎加1
return OK;
}
q = L;
p = ( LinkList ) malloc ( sizeof ( LNode ) ); //爲文件存儲信息分配空間
if ( !p )
{
printf ("\n分配內存失敗\n");
exit ( ERROR );
}
while ( fread ( &p->data, sizeof( Account ), 1, fp ) )
{
//讀入文件成功時
q->next = p;
p->next = NULL; //讀入有效信息時添加到鏈表中
p = ( LinkList ) malloc ( sizeof ( LNode ) ); //爲下一條信息分配空間
if ( !p )
{
printf ("\n分配內存失敗\n");
exit ( ERROR );
}
q = q->next;
}
free ( p ); //最後一次調用fread函數返回值爲0,最後一次讀入的是無效信息,應釋放爲其分配的內存空間
fclose ( fp ); //關閉文件
return OK;
}
Status Read_Record ( RecordOperation &T ) {
//從文件中讀入操作記錄並存儲在鏈表中
RecordOperation p,q;
FILE *fp = fopen ( RECORDOPERATION_FILENAME, "r" ); //以只讀的方式打開存有操作記錄的文件
if ( !fp )
{
printf ("\n操作信息文件不存在\n\n");
FILE *fp = fopen ( RECORDOPERATION_FILENAME, "wa" );
printf ( "新建操作信息文件成功\n\n" );
}
T = ( RecordOperation ) malloc (sizeof ( Operation ) ); //構建鏈表
if ( !T )
{
printf ("\n分配內存失敗\n");
exit ( ERROR );
}
T->next = NULL;
q = T;
p = ( RecordOperation ) malloc (sizeof ( Operation ) ); //爲文件存儲信息分配空間
if ( !p )
{
printf ("\n分配內存失敗\n");
exit ( ERROR );
}
while ( fread ( &p->data, sizeof( Record ), 1, fp ) )
{
//讀入文件成功時
q->next = p;
p->next = NULL; //讀入有效信息時添加到鏈表中
p = ( RecordOperation ) malloc (sizeof ( Operation ) ); //爲下一條信息分配空間
if ( !p )
{
printf ("\n分配內存失敗\n");
exit ( ERROR );
}
q = q->next;
}
free ( p ); //最後一次調用fread函數返回值爲0,最後一次讀入的是無效信息,應釋放爲其分配的內存空間
fclose ( fp ); //關閉文件
return OK;
}
Status Write_Account ( LinkList &L ) {
//該函數用於把更新後的賬號信息存儲在文件中
LinkList p = L;
FILE *fp = fopen ( USERS_FILENAME, "w" ); //以從頭開始寫的方式打開文件
if ( !fp )
{
printf("\n保存文件失敗\n");
exit ( ERROR );
}
while ( p )
{
//將更新後的信息寫入文件
fwrite ( &p->data, sizeof( Account ), 1, fp );
p = p->next;
}
fclose ( fp ); //關閉文件
return OK;
}
Status Write_Record ( RecordOperation &T ) {
//該函數用於把更新後的操作記錄存儲在文件中
RecordOperation p = T->next;
FILE *fp = fopen ( RECORDOPERATION_FILENAME, "w" ); //以從頭開始寫的方式打開文件
if ( !fp )
{
printf("\n保存文件失敗\n");
exit ( ERROR );
}
while ( p )
{
//將更新後的信息寫入文件
fwrite ( &p->data, sizeof( Record ), 1, fp );
p = p->next;
}
fclose ( fp ); //關閉文件
return OK;
}
void Record_Operation ( RecordOperation &T, Record rp ) {
//該函數用於添加一個賬號的操作記錄
RecordOperation m, n = T;
m = ( RecordOperation ) malloc ( sizeof ( Operation ) );
if ( !m )
{
printf ( "\n爲操作記錄分配內存失敗\n" );
exit ( ERROR );
}
time_t t;
struct tm * lt;
time ( &t ); //獲取Unix時間戳。
lt = localtime (&t); //轉爲時間結構
rp.time_year = lt->tm_year+1900;
rp.time_mon = lt->tm_mon + 1;
rp.time_day = lt->tm_mday;
rp.time_hour = lt->tm_hour;
rp.time_min = lt->tm_min;
rp.time_sec = lt->tm_sec;
m->data = rp;
while ( n->next )
{
n = n->next;
}
n->next = m;
m->next = NULL;
}
Status Register ( LinkList &L, RecordOperation &T ) {
//該函數用於註冊一個新賬戶
Record rp; //記錄本次操作相關信息
Account enroll; //記錄正在註冊的賬戶信息
enroll.balance = 0; //餘額初始化爲0
LinkList p = L, q; //q用於搜索已有賬戶信息並與正在註冊賬戶的信息進行比對
printf ( "\n請輸入註冊人姓名:\n\n" );
scanf ( "%s", enroll.name );
while ( p->next )
{
//比對正在註冊的賬戶信息與已註冊過的賬戶信息
if ( strcmp ( p->next->data.name, enroll.name ) == 0 ) //當正在註冊賬戶姓名已存在時
{
printf ( "\n此身份信息已被註冊\n\n" );
return OVERFLOW;
}
p = p->next;
}
q = ( LinkList ) malloc ( sizeof ( LNode ) ); //比對完畢爲正在註冊賬戶信息分配存儲空間
if ( !q )
{
printf ( "\n無法分配存儲空間,註冊失敗\n\n" );
return OVERFLOW;
}
else
{
enroll.number = L->data.number + 1; //以註冊過的最大賬號爲基礎加1作爲正在註冊的賬號
L->data.number ++ ; //記錄現有的最大賬號
p->next = q;
q->next = NULL;
q->data = enroll;
rp.record_accont = enroll.number; //記錄註冊的賬號
strcpy ( rp.record_name, "註冊" ); //記錄本次操作名稱爲“註冊”
Record_Operation ( T, rp ); //調用函數添加本次操作記錄
printf ( "\n註冊成功! 賬號爲 %.0lf \n\n", q->data.number );
return OK;
}
}
Status Query ( LinkList L ) {
//該函數用於查詢一個賬戶的信息
int i = 0;
LinkList p = L->next;
printf ( "請選擇查詢方式: 1:通過賬號查詢 2:通過姓名查詢\n" );
scanf ( "%d", &i );
while ( i != 1 && i != 2 )
{
printf ( "\n輸入的指令無效\n\n" );
printf ( "請選擇查詢方式: 1:通過賬號查詢 2:通過姓名查詢\n" );
scanf ( "%d", &i );
}
if ( i == 1 )
{
double number; //將要查詢的賬號
printf ( "請輸入要查詢的賬號:" );
scanf ( "%lf", &number );
while ( p )
{
if ( number == p->data.number ) //比對賬號信息
{
break;
}
p = p->next;
}
}
else if ( i == 2 )
{
char name[11]; //將要查詢的姓名
printf ( "請輸入將要查詢賬戶戶主姓名: " );
scanf ( "%s", name );
while ( p )
{
if ( strcmp ( name, p->data.name ) == 0 ) //比對姓名信息
{
break;
}
p = p->next;
}
}
if ( !p )
{
printf ( "\n該賬戶不存在\n\n\n" );
return OVERFLOW;
}
else
{
printf ( "用戶姓名:%s 用戶賬號:%.0lf 餘額:%d\n\n\n", p->data.name, p->data.number, p->data.balance );
return OK;
}
}
void Query_Record ( RecordOperation T ) {
//該函數用於查詢一個賬號的所有操作記錄,包括已經註銷過的賬號
double number;
int i = 0;
RecordOperation p = T->next;
printf ( "\n請輸入想要查詢的賬號:" );
scanf ( "%lf", &number );
printf ( "\n賬戶:%.0lf 的操作記錄 : \n\n", number );
while ( p )
{
if ( p->data.record_accont == number )
{
printf("%d/%d/%d/%d:%d:%d",p->data.time_year,p->data.time_mon,p->data.time_day,p->data.time_hour,p->data.time_min,p->data.time_sec);
printf(" %s", p->data.record_name );
if ( strcmp ( p->data.record_name, "註冊" ) !=0 && strcmp ( p->data.record_name, "註銷" ) != 0 )
{
printf ( " %d 元\n\n",p->data.money_number );
}
else
{
printf ( "\n\n" );
}
i ++;
}
p = p->next;
}
if ( i == 0 )
{
printf ( "\n暫無此賬號操作記錄\n\n\n" );
}
}
Status Delete ( LinkList &L, RecordOperation &T ) {
//該函數用於註銷一個賬戶
int i;
Record rp; //記錄本次操作相關信息
LinkList q = L, p = L->next;
change:
printf( "\n請選擇: 1:通過賬號註銷 2:通過姓名註銷 0:退出\n" );
scanf ( "%d", &i );
if ( i == 1 || i== 2 )
{
if ( i == 1 )
{
double number; //將要註銷的賬號
printf ( "\n請輸入要註銷賬戶的賬號:" );
scanf ( "%lf", &number );
while ( p )
{
if ( number == p->data.number )
{
break;
}
p = p->next;
q = q->next;
}
}
else
{
char name[11];
printf ( "\n請輸入將要註銷賬戶戶主姓名: " );
scanf ( "%s", name );
while ( p )
{
if ( strcmp ( name, p->data.name ) == 0 )
{
break;
}
p = p->next;
q = q->next;
}
}
if ( p )
{
printf ( "\n是否要註銷此賬戶? 姓名:%s 賬號:%.0lf 當前餘額:%d\n", p->data.name, p->data.number, p->data.balance );
printf ( "\n1:是 2:否\n" );
scanf ( "%d", &i );
if ( i == 1 )
{
q->next = p->next;
strcpy ( rp.record_name, "註銷" );
rp.record_accont = p->data.number;
free ( p );
Record_Operation ( T, rp );
printf ( "\n註銷成功\n\n" );
return OK;
}
}
else
{
printf ( "\n沒有找到該賬戶\n" );
return ERROR;
}
}
else if ( i == 0 )
{
return OVERFLOW;
}
else
{
printf ( "\n輸入的指令無效\n" );
goto change;
}
}
Status Deposit ( LinkList &L, RecordOperation &T ) {
//該函數用於向一個賬戶存款
Record rp; //記錄本次操作相關信息
int money_number;
double number;
LinkList p = L->next;
printf ( "\n請輸入存款帳號:" );
scanf ( "%lf", &number );
while ( p )
{
if ( p->data.number == number )
{
printf ( "\n賬戶信息: 賬號:%.0lf 姓名:%s 餘額:%d\n", p->data.number, p->data.name, p->data.balance );
break;
}
p = p->next;
}
if ( !p )
{
printf ( "\n輸入賬號有誤\n\n\n" );
return ERROR;
}
else
{
printf ( "\n請輸入存款金額(必須是整數):" );
scanf ( "%d", &money_number );
p->data.balance += money_number;
printf ( "\n存款成功! 餘額:%d\n\n", p->data.balance );
strcpy ( rp.record_name, "存款" );
rp.record_accont = number;
rp.money_number = money_number;
Record_Operation ( T, rp );
return OK;
}
}
Status TakeOut ( LinkList &L, RecordOperation &T ) {
//該函數用於從一個賬戶中取款
Record rp; //記錄本次操作相關信息
int money_number;
double number;
LinkList p = L->next;
printf ( "\n請輸入取款帳號:" );
scanf ( "%lf", &number );
while ( p )
{
if ( p->data.number == number )
{
printf ( "\n賬戶信息: 賬號:%.0lf 姓名:%s 餘額:%d\n\n", p->data.number, p->data.name, p->data.balance );
break;
}
p = p->next;
}
if ( !p )
{
printf ( "\n輸入賬號有誤\n\n\n" );
return ERROR;
}
else
{
printf ( "\n請輸入取款金額(必須是整數);" );
scanf ( "%d", &money_number );
if ( p->data.balance < money_number )
{
printf ( "\n餘額不足\n" );
return ERROR;
}
else
{
p->data.balance -= money_number;
printf ( "\n取款成功! 餘額:%d\n\n", p->data.balance );
strcpy ( rp.record_name, "取款" );
rp.record_accont = number;
rp.money_number = money_number;
Record_Operation ( T, rp );
return OK;
}
}
}
void Overview ( LinkList L ) {
//該函數用於瀏覽所有賬戶信息
LinkList p = L->next;
if ( !p )
{
printf ( "\n暫無用戶信息\n" );
}
while ( p )
{
printf ( "\n賬號:%.0lf 姓名:%-10s 餘額:%d\n", p->data.number, p->data.name, p->data.balance );
p = p->next;
}
printf ( "\n\n" );
}
int main()
{
LinkList L;
RecordOperation T;
int i;
Read_Account ( L );
Read_Record ( T );
printf ( "請選擇操作: 1:註冊賬號 3:存款 5:查詢所有賬戶 7:查詢一個賬號的操作記錄\n" );
printf ( " 2:註銷賬號 4:取款 6:查詢指定賬戶 0:退出\n\n" );
scanf ( "%d", &i );
while ( i )
{
switch ( i )
{
case 1: Register ( L, T );
break;
case 2: Delete ( L, T );
break;
case 3: Deposit ( L, T );
break;
case 4: TakeOut ( L, T );
break;
case 5: Overview ( L );
break;
case 6: Query ( L );
break;
case 7: Query_Record ( T );
}
printf ( "請選擇操作: 1:註冊賬號 3:存款 5:查詢所有賬戶 7:查詢一個賬號的操作記錄\n" );
printf ( " 2:註銷賬號 4:取款 6:查詢指定賬戶 0:退出\n\n" );
scanf ( "%d", &i );
}
Write_Account ( L );
Write_Record ( T );
return 0;
}