(1)熟练掌握文件操作相关函数,包括文本文件和二进制文件的操作
(2)熟练掌握链表的基本操作,包括链表的插入、删除和查找
(3)进一步应用文件包含等编译预处理命令,优化软件结构。
沿用第一次的main.cpp 第三次的tool.h,tool.cpp
card.h
卡片头文件
#ifndef Card_H
#define Card_H
typedef struct Card {
char aName[18]; //卡号
char aPwd[8]; //密码
int nStatus; //卡状态(0-未上机;1-正在上机;2-已注销;3-失效)
time_t tStart; //开卡时间
time_t tEnd; //卡的截止时间
float fTotalUse; //累计金额
time_t tLast; //最后使用时间
int nUseCount; //使用次数
float fBalance; //余额
int nDel; //删除标识 0-未删除,1-删除
struct Card* next; //指向下一个卡的指针
}Card;
void addCard(Card *card, char no[], char pwd[], float balance);
Card* initial();
Card* queryCard(Card *card, char no[]);
Card* queryCards(Card *card, char no[]);
int delCard(Card *card, char no[]);
float spend(Card *card,time_t tm);
Card* showCard();
#endif
卡片源文件
card.cpp
#define _CRT_SECURE_NO_WARNINGS//消除scanf警告
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "card.h"
#include "card_file.h"
#include "time.h"
void addCard(Card *card, char no[], char pwd[], float balance) {
Card *t;
t = (Card*)malloc(sizeof(Card));
strcpy(t->aName, no);
strcpy(t->aPwd, pwd);
t->nStatus = 0;
t->fTotalUse = 0;
t->fBalance = balance;
t->nUseCount = 0;
t->nDel = 0;
t->tLast = time(NULL);
t->tStart = time(NULL);
t->tEnd = t->tLast + 60 * 60 * 24 * 365;
t->next = card->next;
card->next = t;
saveCard(t);
}
Card* initial() {
Card *card;
card = (Card*)malloc(sizeof(Card));
card->next = NULL;
return card;
}
Card* queryCard(Card *card, char no[]) {
Card *t = card->next;
int flag = 0;
for (; t != NULL; t = t->next) {
if (strcmp(t->aName, no) == 0) {
flag = 1;
break;
}
}
if (flag) return t;
else return NULL;
}
Card* queryCards(Card *card, char no[]) {
Card *t = card->next;
Card *s;
s = (Card*)malloc(sizeof(Card));
s->next = NULL;
for (; t != NULL; t = t->next) {
if (strstr(t->aName, no) != NULL) {
Card *p;
p = (Card*)malloc(sizeof(Card));
strcpy(p->aName, t->aName);
strcpy(p->aPwd, t->aPwd);
p->nStatus = t->nStatus;
p->fTotalUse = t->fTotalUse;
p->fBalance = t->fBalance;
p->nUseCount = t->nUseCount;
p->nDel = t->nDel;
p->tLast = t->tLast;
p->tStart = t->tStart;
p->tEnd = t->tEnd;
p->next = s->next;
s->next = p;
}
}
return s;
}
int delCard(Card *card, char no[]) {
Card *t = card->next;
Card *p = card;
int flag = 0;
for (; t != NULL; p = t, t = t->next) {
if (strcmp(t->aName, no) == 0) {
flag = 1;
p->next = t->next;
t->nDel = 1;
free(t);
break;
}
}
return flag;
}
float spend(Card *card,time_t tm) {
float t = 2.0;
t = t * (tm - card->tLast) / 3600;
return t;
}
/*
Card* showCard() {
Card *card=initial();
card=readCard();
return card;
}
*/
menu.h
菜单头文件
void outputmenu();
void add();
void query();
void del();
void dologin();
void dologout();
menu.cpp
菜单源文件
#define _CRT_SECURE_NO_WARNINGS//消除scanf警告
#include"stdio.h"
#include"stdlib.h"
#include "string.h"
#include "menu.h"
#include "card.h"
#include"card_file.h"
#include"time.h"
Card *card = initial();
void outputmenu() {
do {
char i;
printf("以下为本账户管理系统的菜单界面\n");
printf("1.添加卡\n");
printf("2.查询卡\n");
printf("3.上机\n");
printf("4.下机\n");
printf("5.充值\n");
printf("6.退费\n");
printf("7.查询统计\n");
printf("8.注销卡\n");
printf("0.退出\n");
printf("请输入0-8数字来进行选择\n");
scanf("%c", &i);
switch (i) {
case '0': {
exit(0);
break;
}
case '1': {
add();
break;
}
case '2': {
query();
break;
}
case '3': {
dologin();
break;
}
case '4': {
dologout();
break;
}
case '5': {
system("cls");
printf("以下为充值的菜单界面\n");
system("pause");
/*
充值
*/
break;
}
case '6': {
system("cls");
printf("以下为退费的菜单界面\n");
system("pause");
/*
退费
*/
break;
}
case '7': {
system("cls");
printf("以下为查询统计的菜单界面\n");
//showCard();
break;
}
case '8': {
del();
break;
}
default: {
system("cls");
printf("请输入正确的1-8数字\n");
break;
}
}
} while (1);
}
void add() {
system("cls");
card=readCard();
printf("以下为添加卡的菜单界面\n");
printf("请输入需要添加的卡号(长度1-18):\n");
char no[50];
scanf("%s", no);
while (strlen(no) > 18 || queryCard(card, no) != NULL) {
if (strlen(no) > 18) printf("卡号超过18位,请重新输入卡号(长度1-18):\n");
else printf("该卡号已存在请重新输入卡号(长度1-18):\n");
scanf("%s", no);
}
char pwd[30];
printf("请输入密码(长度1-8):\n");
scanf("%s", pwd);
while (strlen(pwd) > 8) {
printf("密码超过8位,请重新输入密码(长度1-8):\n");
scanf("%s", pwd);
}
float balance;
printf("请输入开卡金额(人民币):\n");
scanf("%f", &balance);
printf("添加卡的信息如下:\n");
printf("卡号\t密码\t状态\t金额\n");
printf("%s\t%s\t\t%.1f\n", no, pwd, balance);
addCard(card, no, pwd, balance);
int i;
printf("1.继续添加\n");
printf("2.返回上级菜单\n");
printf("0.退出\n");
scanf("%d", &i);
switch (i) {
case 0: {
exit(0); break;
}
case 1: {
add(); break;
}
case 2: {
break;
}
}
}
void query() {
system("cls");
card=readCard();
printf("以下为查询卡的菜单界面\n");
printf("请输入需要查询的卡号(长度1-18):\n");
char no[50];
scanf("%s", no);
while (strlen(no) > 18) {
if (strlen(no) > 18) printf("卡号超过18位,请重新输入卡号(长度1-18):\n");
scanf("%s", no);
}
Card *t = queryCard(card, no);
if (t == NULL) {
Card *s = queryCards(card, no);
if (s->next != NULL) {
printf("查询卡的信息如下:\n");
printf("卡号\t状态\t余额\t累计使用\t使用次数\t上次使用时间\n");
while (s->next != NULL) {
t = s->next;
s = s->next;
struct tm *p = localtime(&t->tLast);
printf("%s\t%d\t%.1f\t%.1f\t\t%d\t", t->aName, t->nStatus, t->fBalance, t->fTotalUse, t->nUseCount);
printf("%4d-", p->tm_year + 1900);
printf("%02d-", p->tm_mon + 1);
printf("%02d ", p->tm_mday);
printf("%02d:%02d:%02d\n", p->tm_hour, p->tm_min, p->tm_sec);
}
}
else printf("查询失败!\n");
}
else {
printf("查询卡的信息如下:\n");
printf("卡号\t状态\t余额\t累计使用\t使用次数\t上次使用时间\n");
struct tm *p = localtime(&t->tLast);
printf("%s\t%d\t%.1f\t%.1f\t\t%d\t", t->aName, t->nStatus, t->fBalance, t->fTotalUse, t->nUseCount);
printf("%4d-", p->tm_year + 1900);
printf("%02d-", p->tm_mon + 1);
printf("%02d ", p->tm_mday);
printf("%02d:%02d:%02d\n", p->tm_hour, p->tm_min, p->tm_sec);
}
int i;
printf("1.继续查询\n");
printf("2.返回上级菜单\n");
printf("0.退出\n");
scanf("%d", &i);
switch (i) {
case 0: {
exit(0); break;
}
case 1: {
query(); break;
}
case 2: {
break;
}
}
}
void del() {
system("cls");
card = readCard();
printf("以下为注销卡的菜单界面\n");
printf("请输入需要注销的卡号(长度1-18):\n");
char no[50];
scanf("%s", no);
while (strlen(no) > 18 || queryCard(card, no) == NULL) {
if (strlen(no) > 18) printf("卡号超过18位,请重新输入卡号(长度1-18):\n");
else printf("该卡号不存在请重新输入卡号(长度1-18):\n");
scanf("%s", no);
}
Card *t = queryCard(card, no);
char pwd[30];
printf("请输入上机密码(长度1-8):\n");
scanf("%s", pwd);
while (strlen(pwd) > 8) {
printf("密码超过8位,请重新输入密码(长度1-8):\n");
scanf("%s", pwd);
}
if (strcmp(pwd, t->aPwd) == 0) {
if (updateCard(t, 2) == 1) printf("删除成功!\n");
else printf("删除失败!\n");
}
else printf("密码错误!\n");
int i;
printf("1.继续删除\n");
printf("2.返回上级菜单\n");
printf("0.退出\n");
scanf("%d", &i);
switch (i) {
case 0: {
exit(0); break;
}
case 1: {
del(); break;
}
case 2: {
break;
}
}
}
void dologin() {
system("cls");
card=readCard();
printf("以下为上机的菜单界面\n");
printf("请输入上机卡号(长度1-18):\n");
char no[50];
scanf("%s", no);
while (strlen(no) > 18 || queryCard(card, no) == NULL) {
if (strlen(no) > 18) printf("卡号超过18位,请重新输入卡号(长度1-18):\n");
else printf("该卡号不存在请重新输入卡号(长度1-18):\n");
scanf("%s", no);
}
Card *t = queryCard(card, no);
char pwd[30];
printf("请输入上机密码(长度1-8):\n");
scanf("%s", pwd);
while (strlen(pwd) > 8) {
printf("密码超过8位,请重新输入密码(长度1-8):\n");
scanf("%s", pwd);
}
if (strcmp(pwd,t->aPwd) == 0) {
if (t->nStatus == 0) {
if (t->fBalance > 0) {
printf("上机信息如下:\n");
printf("卡号\t余额\t上机时间\n");
time_t tm = time(NULL);
struct tm *p = localtime(&tm);
printf("%s\t%.1f\t%04d-%02d-%02d %02d:%02d:%02d\n", t->aName, t->fBalance, p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
t->tLast = tm;
if (updateCard(t, 1) != 1) {
printf("文件写入失败!\n");
}
else printf("上机成功!\n");
}
else printf("该卡余额不足,上机失败!\n");
}
else printf("该卡正在上机或已注销或失效,上机失败!\n");
}
else printf("密码不正确,上机失败!\n");
int i;
printf("1.继续上机\n");
printf("2.返回上级菜单\n");
printf("0.退出\n");
scanf("%d", &i);
switch (i) {
case 0: {
exit(0); break;
}
case 1: {
dologin(); break;
}
case 2: {
break;
}
}
}
void dologout() {
system("cls");
card = readCard();
printf("以下为下机的菜单界面\n");
printf("请输入下机卡号(长度1-18):\n");
char no[50];
scanf("%s", no);
while (strlen(no) > 18 || queryCard(card, no) == NULL) {
if (strlen(no) > 18) printf("卡号超过18位,请重新输入卡号(长度1-18):\n");
else printf("该卡号不存在请重新输入卡号(长度1-18):\n");
scanf("%s", no);
}
Card *t = queryCard(card, no);
char pwd[30];
printf("请输入下机密码(长度1-8):\n");
scanf("%s", pwd);
while (strlen(pwd) > 8) {
printf("密码超过8位,请重新输入密码(长度1-8):\n");
scanf("%s", pwd);
}
if (strcmp(pwd, t->aPwd) == 0) {
if (t->nStatus == 1) {
printf("下机信息如下:\n");
printf("卡号\t消费\t余额\t上机时间\t下机时间\n");
time_t tmp;
time(&tmp);
struct tm *q = localtime(&t->tLast);
float spd = spend(t,tmp);
t->fBalance -= spd;
t->fTotalUse += spd;
printf("%s\t%.1f\t%.1f\t%04d-%02d-%02d %02d:%02d:%02d\t", t->aName, spd, t->fBalance, q->tm_year + 1900, q->tm_mon + 1, q->tm_mday, q->tm_hour, q->tm_min, q->tm_sec);
struct tm *p = localtime(&tmp);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
t->tLast = tmp;
if (updateCard(t, 0) != 1) {
printf("文件写入失败!\n");
}
else printf("下机成功!\n");
}
else printf("该卡未上机或已注销或失效,上机失败!\n");
}
else printf("密码不正确,上机失败!\n");
int i;
printf("1.继续下机\n");
printf("2.返回上级菜单\n");
printf("0.退出\n");
scanf("%d", &i);
switch (i) {
case 0: {
exit(0); break;
}
case 1: {
dologout(); break;
}
case 2: {
break;
}
}
}
card_file.h
卡片文件头文件
#include "card.h"
void saveCard(Card *card);
Card* readCard();
int updateCard(Card *card, int nStatus);
card_file.cpp
卡片文件源文件
#define _CRT_SECURE_NO_WARNINGS//消除scanf警告
#include "stdio.h"
#include"stdlib.h"
#include "card.h"
#include "time.h"
#include "string.h"
#include "tool.h"
#include "card_file.h"
void saveCard(Card *card) {
FILE *file;
time_t t = time(NULL);
struct tm *p = localtime(&t);
if ((file = fopen("C:\\Users\\HU\\Desktop\\card.txt", "a")) != NULL) {
fprintf(file, "%s\t%s\t%d\t%4d%02d%02d-%02d:%02d:%02d\t%4d%02d%02d-%02d:%02d:%02d\t%.1f\t%4d%02d%02d-%02d:%02d:%02d\t%d\t%.1f\t%d\n",
card->aName, card->aPwd, card->nStatus, p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec,
p->tm_year + 1901, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, card->fTotalUse,
p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, card->nUseCount, card->fBalance, card->nDel);
}
else printf("文件打开失败!\n");
fclose(file);
}
Card* readCard() {
Card *card = initial();
FILE *file;
file = fopen("C:\\Users\\HU\\Desktop\\card.txt", "a"); //如果文件不存在则创建一个文件
fclose(file);
char time_start[50], time_end[50], time_last[50];
time_t t_start, t_end, t_last;
if ((file = fopen("C:\\Users\\HU\\Desktop\\card.txt", "r")) != NULL) {
while (!feof(file)) {
Card *t;
t = (Card*)malloc(sizeof(Card));
if (fscanf(file, "%s %s %d %s %s %f %s %d %f %d",
t->aName, t->aPwd, &t->nStatus, time_start, time_end,
&t->fTotalUse, time_last, &t->nUseCount, &t->fBalance, &t->nDel) == EOF) break;
t->tStart = stringToTime(time_start);
t->tEnd = stringToTime(time_end);
t->tLast = stringToTime(time_last);
/*t_start = t->tStart;
//t_end = t->tEnd;
//t_last = t->tLast;
//struct tm *p = localtime(&t_start);
//printf("%s\t%s\t%d\t", t->aName, t->aPwd, t->nStatus);
//printf("%4d%02d%02d-%02d:%02d:%02d\t", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
//p = localtime(&t_end);
//printf("%4d%02d%02d-%02d:%02d:%02d\t", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
//printf("%.1f\t", t->fTotalUse);
//p = localtime(&t_last);
//printf("%4d%02d%02d-%02d:%02d:%02d\t", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
//printf("%d\t%.1f\t%d\n", t->nUseCount,t->fBalance,t->nDel);
*/
if (t->nStatus < 2 && t->nDel != 1) {
t->next = card->next;
card->next = t;
}
}
}
else {
printf("文件读取失败!");
}
fclose(file);
return card;
}
int updateCard(Card *card, int nStatus) {
FILE *file;
time_t t = time(NULL);
struct tm *p = localtime(&t);
time_t t_start, t_end, t_last;
char time_start[50], time_end[50], time_last[50];
int flag = 0;
if ((file = fopen("C:\\Users\\HU\\Desktop\\card.txt", "r+")) != NULL) {
Card *t;
t = (Card*)malloc(sizeof(Card));
while (fscanf(file, "%s %s %d %s %s %f %s %d %f %d",
t->aName, t->aPwd, &t->nStatus, time_start, time_end,
&t->fTotalUse, time_last, &t->nUseCount, &t->fBalance, &t->nDel) != EOF) {
if (strcmp(card->aName, t->aName) == 0) {
fseek(file, -83, SEEK_CUR);//不同格式不一定是-83
if (nStatus != 2) {
fprintf(file, "%s\t%s\t%d\t%s\t%s\t%.1f\t%4d%02d%02d-%02d:%02d:%02d\t%d\t%.1f\t%d\n",
card->aName, card->aPwd, nStatus, time_start, time_end, card->fTotalUse,
p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, card->nUseCount+1, card->fBalance, 0);
}
else {
fprintf(file, "%s\t%s\t%d\t%s\t%s\t%.1f\t%4d%02d%02d-%02d:%02d:%02d\t%d\t%.1f\t%d\n",
card->aName, card->aPwd, nStatus, time_start, time_end, card->fTotalUse,
p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, card->nUseCount, card->fBalance, 1);
}
flag = 1;
break;
}
}
}
fclose(file);
return flag;
}