C语言综合实验(六)之计费管理系统的基本功能实现

实验内容

(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;
}
  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
计费管理系统是一种用于管理和记录用户及其消费信息的系统,文件存储管理是该系统的重要组成部分之一。C语言综合实验(三)计费管理系统的文件存储管理主要是指将用户和消费数据存储到文件中,以保证数据的可持久化。本文将针对以下几个方面进行详细阐述: 1.文件存储的基础知识 文件是计算机上的一种数据存储方式,是对数据进行长期存储和保护的便捷途径。文件存储的基本单位是字节(Byte),文件中的数据按照一定的格式被存储到硬盘等媒介中。文件的读写是程序与外部环境(例如硬盘)进行数据交互的方式之一。常见的文件类型有文本文件和二进制文件两种。文本文件是指由若干个符合编码规范的字符序列组成的文件,例如txt文件,二进制文件是指由0和1组成的文件,例如图片、音频等文件。 2.文件读写的方法 在C语言中,文件读写的操作包含三个主要步骤:打开文件、读取/写入文件内容和关闭文件。文件的打开和关闭使用fopen和fclose函数,读取/写入文件内容使用fread和fwrite函数。这些函数都是C语言标准库中的常用函数,定义在stdio.h头文件中。在进行文件读写时,需要指定文件名、访问模式、数据读写位置等参数信息。 3.计费管理系统的文件存储 计费管理系统需要将用户信息和消费信息存储到文件中,以便在程序下次启动时能够读取之前的数据并进行数据维护工作。该系统可以采用文本文件的形式存储数据,使用逗号、空格等分隔符将不同字段的数据分开。例如,可以将用户信息分为编号、姓名、电话三个字段,消费信息分为时间、原因、金额等字段,每个字段之间使用逗号分隔。存储数据的文件名可以自行定义,例如”user.txt”、”consume.txt”等。 4.文件读写的错误处理 文件读写过程中可能会出现很多问题,例如文件不存在、打开文件失败、读写错误等情况,需要做好相应的错误处理工作。在C语言中,可以使用fopen函数设置访问文件的模式(只读、只写、读写)、文件操作指针(文件开头、文件结尾、指定位置)等信息,并通过返回值判断文件是否打开成功。另外,在使用完文件后,需要调用fclose函数关闭文件以释放资源。如果在读写过程中出现错误,可以使用ferror函数进行错误检查并进行错误处理。 综上所述,计费管理系统的文件存储管理是一项十分重要的任务,需要对文件的打开、读写、关闭、错误处理等操作进行认真细致的处理,以保证数据的完整性和正确性。在实际操作中,还需要考虑数据格式的统一性、文件的备份和恢复、文件操作并发性等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值