停车场收费系统
来源:互联网 发布:软件项目实施总结报告 编辑:程序博客网 时间:2024/04/29 05:53
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "api.h"
#include "SubwayCharge.h"
FILE *pfWrite = NULL;
#ifdef __cplusplus
extern "C"
{
#endif
int opGetDistanceBetweenTwoStation(char* sStartStation, char* sObjectStation, int* pnDistance);
int ComputeBasePrice(int distance);
int ComputeChargePrice(int nBasePrice,TravelInfo_ST* pstTravelInfo);
int GetSameStationChargePrice(TravelInfo_ST* pstTravelInfo);
int ChargeProcess(int nChargePrice, TravelInfo_ST* pstTravelInfo);
int AddHistoryItemOnListTail(int nChargePrice, TravelInfo_ST* pstTravelInfo);
int IsCheckTimeValid(QueryCond_ST* pstQueryCond, LogItem_ST *logAddr);
HistoryItem *removeNodeByCardNo(int iCradNo);
void removeHistoryList(void);
int IsValidTravel(TravelInfo_ST* pstTravelInfo);
void searchHistoryNode(int iCardNo);
void Swap(LogItem_ST &logItemA, LogItem_ST &logItemB);
void SortByCardID(LogItem_ST logItems[], int nItems);
void readFile(void);
void writeFile(HistoryItem *historyFile);
void queryLogInf(QueryCond_ST* pstQueryCond);
#ifdef __cplusplus
}
#endif
CardStat_EN g_CardStatusInfo[MAX_MEMBER_NUM] = {CARD_VALID};
/*****************************************************************************
函 数 名 : main
功能描述 : 主入口参数(考生无需更改)
输入参数 : argc 程序启动时的参数个数
argv 程序启动时的参数
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void main(int argc, char* argv[])
{
pHeadHistory = NULL;
readFile();
/*启动Socket服务侦听5555端口(apiServerStart函数在lib库已实现)*/
apiServerStart(argc, argv);
return;
}
/*****************************************************************************
函 数 名 : opResetProc
功能描述 : 考生需要实现的接口
完成程序初始化,或程序功能复位操作
程序启动自动调用该函数,r/R命令时自动调用该函数
输入参数 : 无
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void opResetProc(void)
{
int i = 0;
for(i = 0; i < MAX_MEMBER_NUM; i++)
{
g_CardStatusInfo[i] = CARD_VALID; //卡号为0-9的可用
}
}
/*****************************************************************************
函 数 名 : opChargeProc
功能描述 : 考生需要实现的接口
完成请求扣费的功能(详见试题规格说明)
c/C命令时自动调用该函数
输入参数 : pstTravelInfo 单次乘车记录信息
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void opChargeProc(TravelInfo_ST* pstTravelInfo)
{
int nBasePrice = 0;
int nChargePrice = 0;
//首先判断卡是否可用
if(CARD_UNVAILD == g_CardStatusInfo[pstTravelInfo->nCardNo])
{
apiPrintErrInfo(E22);
return;
}
//其次判断出站时间是否大于等于入站时间
if(apiTimeDiff(pstTravelInfo->nInHour,pstTravelInfo->nInMinute,pstTravelInfo->nOutHour,pstTravelInfo->nOutMinute) > 0)
{
apiPrintErrInfo(E02);
apiWriteLog(0, pstTravelInfo, RET_ERROR);
return;
}
//最后判断路径是否有效
if (RET_ERROR == IsValidTravel(pstTravelInfo))
{
apiPrintOpStatusInfo(I10, pstTravelInfo->nCardNo, pstTravelInfo->nCardMoney);
return;
}
int nDistance = 0;
int flag = 0;
//计算两个站点之间的距离
flag = opGetDistanceBetweenTwoStation(pstTravelInfo->sInStation ,pstTravelInfo->sOutStation, &nDistance);
if(RET_ERROR == flag)
{
apiPrintOpStatusInfo(I10,pstTravelInfo->nCardNo, pstTravelInfo->nCardMoney);
apiWriteLog(0, pstTravelInfo, RET_ERROR);
return;
}
//计算基本票价
nBasePrice = ComputeBasePrice(nDistance);
//计算扣费票价
nChargePrice = ComputeChargePrice(nBasePrice,pstTravelInfo);
//进行扣费,并将扣费记录写入链表尾
ChargeProcess(nChargePrice, pstTravelInfo);
return ;
}
/*****************************************************************************
函 数 名 : opQueryLogProc
功能描述 : 考生需要实现的接口
完成查询乘车记录日志的功能(详见试题规格说明)
q/Q命令时自动调用该函数
输入参数 : pstQueryCond 日志查询条件
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void opQueryLogProc(QueryCond_ST* pstQueryCond)
{
int nTimeDiff = 0;
if (NULL == pstQueryCond)
{
//apiPrintErrInfo(E99);
return;
}
nTimeDiff = apiTimeDiff(pstQueryCond->nStartHour,pstQueryCond->nStartMinute,
pstQueryCond->nEndHour,pstQueryCond->nEndMinute);
if (nTimeDiff > 0)
{
apiPrintErrInfo(E02);
return;
}
//printf("%d\n", pstQueryCond->nCardNo);
if(CARD_UNVAILD == g_CardStatusInfo[pstQueryCond->nCardNo])
{
apiPrintErrInfo(E22);
return;
}
queryLogInf(pstQueryCond);
return;
}
/*****************************************************************************
函 数 名 : opQueryHistoryChargeListProc
功能描述 : 考生需要实现的接口
完成查询指定卡号的票卡消费历史记录功能(详见试题规格说明)
输入参数 : iCardNo 待查询的票卡卡号
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void opQueryHistoryChargeListProc(int iCardNo)
{
HistoryItem *p1 = pHeadHistory;
if (pHeadHistory == NULL)
{
apiPrintErrInfo(E21);
return;
}
if (g_CardStatusInfo[iCardNo] == CARD_UNVAILD)
{
apiPrintErrInfo(E22);
return;
}
if (0 == iCardNo)
{
while(p1 != NULL)
{
apiPrintHistoryChargeList(p1);
writeFile(p1);
p1 = p1->pNextHistory;
}
}
else
searchHistoryNode(iCardNo);
fclose(pfWrite);
}
/*****************************************************************************
函 数 名 : opDestroyCardProc
功能描述 : 考生需要实现的接口
完成注销指定卡号的票卡消费历史记录功能(详见试题规格说明)
输入参数 : iCardNo 待注销的票卡卡号
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void opDestroyCardProc(int iCardNo)
{
int i = 0;
if ((iCardNo < 0) || (iCardNo > 9))
{
apiPrintErrInfo(E99);
return;
}
if ((0 == iCardNo) && (g_CardStatusInfo[0] == CARD_VALID))
{
for(i = 0; i < MAX_MEMBER_NUM; i++)
{
g_CardStatusInfo[i] = CARD_UNVAILD; //卡号为1-9的不可用
}
apiPrintOpStatusInfo(I22, 0, 0);
removeHistoryList();
}
else
{
if (g_CardStatusInfo[iCardNo] == CARD_VALID)
{
g_CardStatusInfo[iCardNo] = CARD_UNVAILD;
apiPrintOpStatusInfo(I22, iCardNo, 0);
removeNodeByCardNo(iCardNo);
}
else
{
apiPrintErrInfo(E22);
return;
}
}
}
/*其他函数定义考生根据功能需要补充*/
void readFile(void)
{
STA_INFO_S *p1, *p2;
FILE *pf = NULL;
char station[4];
int distance;
//打开读取
pf = fopen("d:\\station_info.txt", "r");
pfWrite = fopen("d:\\SubwayCharge.txt", "w");
if (NULL == pf)
{
printf("error");
return;
}
while(EOF != fscanf(pf, "%s %d\n", station, &distance))
{
p1 = (STA_INFO_S *)malloc(sizeof(STA_INFO_S));
strcpy(p1->sStation, station);
p1->dist = distance;
if (NULL == g_StationList)
{
g_StationList = p1;
p2 = p1;
}
else
{
p2->pNextStation = p1;
p2 = p1;
}
p2->pNextStation = NULL;
}
/*q = g_StationList;
while (q)
{
printf("%s %d\n", q->sStation, q->dist);
q = q->pNextStation;
};*/
fclose(pf);
}
void writeFile(HistoryItem *historyFile)
{
char text[100] = {"卡号:"};
char nCardNo[3] = {" "};
char nInHour[4];
char nInMin[4];
char nOutHour[4];
char nOutMin[4];
char nMoney[4];
sprintf(nCardNo, "%d", historyFile->nCardNo);
sprintf(nMoney, "%d", historyFile->nMoney);
sprintf(nInHour, "%d", historyFile->nInHour);
sprintf(nInMin, "%d", historyFile->nInMin);
sprintf(nOutHour, "%d", historyFile->nOutHour);
sprintf(nOutMin, "%d", historyFile->nOutMin);
strcat(text, nCardNo);
switch(historyFile->enCardType)
{
case CARDTYPE_A: strcat(text, " 卡类别:单程表 进站时间:"); break;
case CARDTYPE_B: strcat(text, " 卡类别:老年卡 进站时间:"); break;
case CARDTYPE_C: strcat(text, " 卡类别:普通卡 进站时间:"); break;
}
strcat(text, nInHour);
strcat(text, ":");
if ((historyFile->nInMin < 10) || ((historyFile->nInMin)%10 == 0))
strcat(text, "0");
strcat(text, nInMin);
strcat(text, " 进站名称:");
strcat(text, historyFile->sInStation);
strcat(text, " 出站时间:");
strcat(text, nOutHour);
strcat(text, ":");
if((historyFile->nOutMin < 10) || ((historyFile->nOutMin)%10 == 0))
strcat(text, "0");
strcat(text, nInMin);
strcat(text, " 出站名称:");
strcat(text, historyFile->sOutStation);
strcat(text, "\n");
printf("%d", strlen(text));
fputs(text, pfWrite);
}
int IsValidTravel(TravelInfo_ST* pstTravelInfo)
{
int i = 0;
STA_INFO_S *p1 = g_StationList;
if (p1 == NULL)
{
apiPrintErrInfo(E99);
return RET_ERROR;
}
for (p1 = g_StationList; p1 != NULL; p1 = p1->pNextStation)
{
if(!strcmp(p1->sStation, pstTravelInfo->sInStation))
{
i = 1;
break;
}
}
for (p1 = g_StationList; p1 != NULL; p1 = p1->pNextStation)
{
if(!strcmp(p1->sStation, pstTravelInfo->sOutStation) && (i = 1))
{
return RET_OK;
}
}
return RET_ERROR;
}
int opGetDistanceBetweenTwoStation(char* sStartStation, char* sObjectStation, int* pnDistance)
{
STA_INFO_S *p1 = NULL;
int startDis = 0, objDis = 0;
if (g_StationList == NULL)
{
printf("error");
return RET_ERROR;
}
for (p1 = g_StationList; p1 != NULL; p1 = p1->pNextStation)
{
if (!strcmp(sStartStation, p1->sStation))
startDis = p1->dist;
if (!strcmp(sObjectStation, p1->sStation))
objDis = p1->dist;
}
*pnDistance = abs(startDis-objDis);
return RET_OK;
}
//计算基本票价
int ComputeBasePrice(int distance)
{
if (0 >= distance)
{
return 0;
}
else if ((0 < distance) && (3 >= distance))
{
return 2;
}
else if ((3 < distance) && (5 >= distance))
{
return 3;
}
else if ((5 < distance) && (10 >= distance))
{
return 4;
}
else
{
return 5;
}
}
//计算扣费票价
int ComputeChargePrice(int baseprice, TravelInfo_ST* pstTravelInfo)
{
int nInHour = 0;
int nInMin = 0;
int nCmpWith07_00 = 0;
int nCmpWith09_00 = 0;
int nCmpWith16_30 = 0;
int nCmpWith18_30 = 0;
int nCmpWith10_00 = 0;
int nCmpWith11_00 = 0;
int nCmpWith15_00 = 0;
int nCmpWith16_00 = 0;
//同站进出
if(0 == strcmp(pstTravelInfo->sInStation, pstTravelInfo->sOutStation))
{
return GetSameStationChargePrice(pstTravelInfo);
}
//非同站进出
else
{
//票卡为单程票
if(CARDTYPE_A == pstTravelInfo->enCardType)
{
return (pstTravelInfo->nCardMoney > baseprice) ? pstTravelInfo->nCardMoney : baseprice;
}
//票卡为非单程票
else
{
nInHour = pstTravelInfo->nInHour;
nInMin = pstTravelInfo->nInMinute;
nCmpWith07_00 = apiTimeDiff(nInHour, nInMin, 7, 0);
nCmpWith09_00 = apiTimeDiff(nInHour, nInMin, 9, 0);
nCmpWith16_30 = apiTimeDiff(nInHour, nInMin, 16, 30);
nCmpWith18_30 = apiTimeDiff(nInHour, nInMin, 18, 30);
if (((0 <= nCmpWith07_00) && (0 > nCmpWith09_00))
|| ((0 <= nCmpWith16_30) && (0 > nCmpWith18_30)))//处于非优惠时段
{
return baseprice;
}
else
{
nCmpWith10_00 = apiTimeDiff(nInHour, nInMin, 10, 0);
nCmpWith11_00 = apiTimeDiff(nInHour, nInMin, 11, 0);
nCmpWith15_00 = apiTimeDiff(nInHour, nInMin, 15, 0);
nCmpWith16_00 = apiTimeDiff(nInHour, nInMin, 16, 0);
if (((0 <= nCmpWith10_00) && (0 > nCmpWith11_00))
|| ((0 <= nCmpWith15_00) && (0 > nCmpWith16_00))) // 处于优惠时段
{
return baseprice/2;
}
else
{
if(CARDTYPE_C == pstTravelInfo->enCardType)
{
return baseprice;
}
else if(CARDTYPE_B == pstTravelInfo->enCardType)
{
return (baseprice*9)/10;
}
}
}
}
}
return 0;
}
//计算同站进出的情况
int GetSameStationChargePrice(TravelInfo_ST* pstTravelInfo)
{
// if(NULL == pstTravelInfo)
int nMoney = 0;
int nTimeDiff = 0;
CardType_EN nCardType;
nMoney = pstTravelInfo->nCardMoney; //卡金额
nCardType= pstTravelInfo->enCardType;
nTimeDiff = apiTimeDiff(pstTravelInfo->nOutHour, pstTravelInfo->nOutMinute, pstTravelInfo->nInHour, pstTravelInfo->nInMinute);
if(nTimeDiff <= 30)
{
if(CARDTYPE_A == nCardType) //单程票
return nMoney;
else
return 0;
}
else
{
if(CARDTYPE_A == nCardType) //单程票
{
return (nMoney>3 ? nMoney:3);
}
else
{
return 3;
}
}
// return 0;
}
int ChargeProcess(int nChargePrice, TravelInfo_ST* pstTravelInfo)
{
int nCardID = pstTravelInfo->nCardNo;
int nLogItems = apiGetLogNum();
//判断扣费票价是否大于卡上余额
if(nChargePrice > pstTravelInfo->nCardMoney)
{
apiPrintOpStatusInfo(I13,nCardID, pstTravelInfo->nCardMoney);
apiWriteLog(0,pstTravelInfo,RET_ERROR);
return RET_ERROR;
}
//计算出消费完成之后的余额
pstTravelInfo->nCardMoney = pstTravelInfo->nCardMoney - nChargePrice;
//如果是单程票
if(CARDTYPE_A == pstTravelInfo->enCardType)
{
apiPrintOpStatusInfo(I11, nCardID, pstTravelInfo->nCardMoney);
}
//非单程票
else
{
if(pstTravelInfo->nCardMoney >= 20)
{
apiPrintOpStatusInfo(I11, pstTravelInfo->nCardNo, pstTravelInfo->nCardMoney);
}
//若果卡内余额小于20的情况,做出提醒
else
{
apiPrintOpStatusInfo(I12, pstTravelInfo->nCardNo, pstTravelInfo->nCardMoney);
}
}
//写日志
apiWriteLog(nChargePrice, pstTravelInfo, RET_OK);
//将扣费记录添加到链表尾
if(RET_OK == AddHistoryItemOnListTail(nChargePrice,pstTravelInfo))
{
return RET_OK;
}
else
{
return RET_ERROR;
}
}
void queryLogInf(QueryCond_ST* pstQueryCond)
{
LogItem_ST tmpLogItem[MAX_LOG_RECORD_NUM];
LogItem_ST *pLogAddr;
int i = 0, j = 0;
int nItems = 0;
int nLogItemCnt = 0;
memset(tmpLogItem, 0, sizeof(LogItem_ST) * MAX_LOG_RECORD_NUM);
pLogAddr = apiGetLogAddr();
nItems = apiGetLogNum();
if (0 == pstQueryCond->nCardNo)
{
for(i = 1; i < MAX_LOG_RECORD_NUM; i++)
{
if(CARD_VALID == g_CardStatusInfo[i])
{
for(j = 0; j < nItems+1; j++)
{
if((i == pLogAddr[j].nCardNo)
&& (RET_OK == IsCheckTimeValid(pstQueryCond,pLogAddr + j)))
{
memcpy(&(tmpLogItem[nLogItemCnt]),&(pLogAddr[j]),sizeof(LogItem_ST));
nLogItemCnt++;
}
}
}
}
}
else
{
for(j = 0; j < nItems; j++)
{
if((pstQueryCond->nCardNo == pLogAddr[j].nCardNo)
&& (RET_OK == IsCheckTimeValid(pstQueryCond,pLogAddr + j)))
{
memcpy(&(tmpLogItem[nLogItemCnt]), &(pLogAddr[j]), sizeof(LogItem_ST));
nLogItemCnt++;
}
}
}
if(nLogItemCnt <= 0)
{
apiPrintErrInfo(E21);
return;
}
else
{
//根据卡号进行排序
SortByCardID(tmpLogItem, nLogItemCnt);
apiPrintLog(tmpLogItem, nLogItemCnt);
}
return;
}
int IsCheckTimeValid(QueryCond_ST* pstQueryCond, LogItem_ST *logAddr)
{
int nQueryStartHour, nQueryStartMin, nQueryEndHour, nQueryEndMin;
int nLogStartHour, nLogStartMin, nLogEndHour, nLogEndMin;
if(NULL == pstQueryCond || NULL == logAddr)
{
apiPrintErrInfo(E99);
return RET_ERROR;
}
nQueryStartHour = pstQueryCond->nStartHour;
nQueryStartMin = pstQueryCond->nStartMinute;
nQueryEndHour = pstQueryCond->nEndHour;
nQueryEndMin = pstQueryCond->nEndMinute;
nLogStartHour = logAddr->nInHour;
nLogStartMin = logAddr->nInMin;
nLogEndHour = logAddr->nOutHour;
nLogEndMin = logAddr->nOutMin;
if((apiTimeDiff(nQueryStartHour, nQueryStartMin, nLogEndHour, nLogEndMin) <= 0)
&& (apiTimeDiff(nLogEndHour,nLogEndMin,nQueryEndHour,nQueryEndMin) <= 0))
{
return RET_OK;
}
else
{
return RET_ERROR;
}
}
void Swap(LogItem_ST &logItemA, LogItem_ST &logItemB)
{
LogItem_ST tmp;
memcpy(&tmp, &logItemA, sizeof(LogItem_ST));
memcpy(&logItemA, &logItemB, sizeof(LogItem_ST));
memcpy(&logItemB, &tmp, sizeof(LogItem_ST));
}
//利用冒泡排序对卡号进行排序
void SortByCardID(LogItem_ST logItems[], int nItems)
{
if(NULL == logItems || nItems <= 0)
{
return;
}
int i = 0, k = nItems;
int flag = 1;
while(flag)
{
flag = 0;
for (i = 1; i < k; i++)
{
if (logItems[i - 1].nCardNo > logItems[i].nCardNo)
{
Swap(logItems[i - 1], logItems[i]);
flag = 1;
}
}
k--;
}
}
int AddHistoryItemOnListTail(int nChargePrice, TravelInfo_ST* pstTravelInfo)
{
HistoryItem *p1, *p2 = pHeadHistory;
p1 = (HistoryItem *)malloc(sizeof(HistoryItem));
p1->enCardType = pstTravelInfo->enCardType;
p1->nCardNo = pstTravelInfo->nCardNo;
p1->nInHour = pstTravelInfo->nInHour;
p1->nInMin = pstTravelInfo->nInMinute;
strcpy(p1->sInStation, pstTravelInfo->sInStation);
p1->nMoney = nChargePrice;
p1->nOutHour = pstTravelInfo->nOutHour;
p1->nOutMin = pstTravelInfo->nOutMinute;
strcpy(p1->sOutStation, pstTravelInfo->sOutStation);
if (NULL == p1)
{
printf("error");
return RET_ERROR;
}
if (NULL == p2)
{
pHeadHistory = p1;
p1->pNextHistory = NULL;
}
else
{
for (p2 = pHeadHistory; ; p2 = p2->pNextHistory)
{
if (p2->pNextHistory == NULL)
{
p2->pNextHistory = p1;
p1->pNextHistory = NULL;
break;
}
}
}
return RET_OK;
}
HistoryItem *removeNodeByCardNo(int iCradNo)
{
HistoryItem *pNode = NULL;
HistoryItem *pDelNode = NULL;
if ((NULL == pHeadHistory) || (iCradNo < 0))
{
//apiPrintErrInfo(E99);
return NULL;
}
while((iCradNo == pHeadHistory->nCardNo))
{
pDelNode = pHeadHistory;
pHeadHistory = pHeadHistory->pNextHistory;
free(pDelNode);
if(pHeadHistory == NULL)
return NULL;
}
for (pNode = pHeadHistory; pNode->pNextHistory!= NULL; )
{
pDelNode = pNode->pNextHistory;
if (pNode->pNextHistory->nCardNo== iCradNo)
{
if (pNode->pNextHistory->pNextHistory == NULL)
{
pNode->pNextHistory = NULL;
pDelNode = pDelNode->pNextHistory;
free(pDelNode);
break;
}
else
{
pNode->pNextHistory = pDelNode->pNextHistory;
free(pDelNode);
}
}
else
pNode = pNode->pNextHistory;
}
if (NULL == pDelNode)
return NULL;
free(pDelNode);
return pHeadHistory;
}
void removeHistoryList(void)
{
HistoryItem *pNode, *pTemp;
if (NULL == pHeadHistory)
{
return;
}
pNode = pHeadHistory;
pTemp = pNode->pNextHistory;
if (pTemp == NULL)
{
free(pNode);
}
else
{
while(pTemp != NULL)
{
free(pNode);
pNode = pTemp;
pTemp = pTemp->pNextHistory;
}
free(pNode);
}
pNode = NULL;
return;
}
void searchHistoryNode(int iCardNo)
{
int i = 0;
HistoryItem *p1;
if (NULL == pHeadHistory)
{
apiPrintErrInfo(E99);
return;
}
for (p1 = pHeadHistory; p1 != NULL; p1 = p1->pNextHistory)
{
if (p1->nCardNo == iCardNo)
{
apiPrintHistoryChargeList(p1);
writeFile(p1);
i = 1;
}
}
if (0 == i)
apiPrintErrInfo(E21);
return;
}
#include <string.h>
#include <stdlib.h>
#include "api.h"
#include "SubwayCharge.h"
FILE *pfWrite = NULL;
#ifdef __cplusplus
extern "C"
{
#endif
int opGetDistanceBetweenTwoStation(char* sStartStation, char* sObjectStation, int* pnDistance);
int ComputeBasePrice(int distance);
int ComputeChargePrice(int nBasePrice,TravelInfo_ST* pstTravelInfo);
int GetSameStationChargePrice(TravelInfo_ST* pstTravelInfo);
int ChargeProcess(int nChargePrice, TravelInfo_ST* pstTravelInfo);
int AddHistoryItemOnListTail(int nChargePrice, TravelInfo_ST* pstTravelInfo);
int IsCheckTimeValid(QueryCond_ST* pstQueryCond, LogItem_ST *logAddr);
HistoryItem *removeNodeByCardNo(int iCradNo);
void removeHistoryList(void);
int IsValidTravel(TravelInfo_ST* pstTravelInfo);
void searchHistoryNode(int iCardNo);
void Swap(LogItem_ST &logItemA, LogItem_ST &logItemB);
void SortByCardID(LogItem_ST logItems[], int nItems);
void readFile(void);
void writeFile(HistoryItem *historyFile);
void queryLogInf(QueryCond_ST* pstQueryCond);
#ifdef __cplusplus
}
#endif
CardStat_EN g_CardStatusInfo[MAX_MEMBER_NUM] = {CARD_VALID};
/*****************************************************************************
函 数 名 : main
功能描述 : 主入口参数(考生无需更改)
输入参数 : argc 程序启动时的参数个数
argv 程序启动时的参数
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void main(int argc, char* argv[])
{
pHeadHistory = NULL;
readFile();
/*启动Socket服务侦听5555端口(apiServerStart函数在lib库已实现)*/
apiServerStart(argc, argv);
return;
}
/*****************************************************************************
函 数 名 : opResetProc
功能描述 : 考生需要实现的接口
完成程序初始化,或程序功能复位操作
程序启动自动调用该函数,r/R命令时自动调用该函数
输入参数 : 无
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void opResetProc(void)
{
int i = 0;
for(i = 0; i < MAX_MEMBER_NUM; i++)
{
g_CardStatusInfo[i] = CARD_VALID; //卡号为0-9的可用
}
}
/*****************************************************************************
函 数 名 : opChargeProc
功能描述 : 考生需要实现的接口
完成请求扣费的功能(详见试题规格说明)
c/C命令时自动调用该函数
输入参数 : pstTravelInfo 单次乘车记录信息
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void opChargeProc(TravelInfo_ST* pstTravelInfo)
{
int nBasePrice = 0;
int nChargePrice = 0;
//首先判断卡是否可用
if(CARD_UNVAILD == g_CardStatusInfo[pstTravelInfo->nCardNo])
{
apiPrintErrInfo(E22);
return;
}
//其次判断出站时间是否大于等于入站时间
if(apiTimeDiff(pstTravelInfo->nInHour,pstTravelInfo->nInMinute,pstTravelInfo->nOutHour,pstTravelInfo->nOutMinute) > 0)
{
apiPrintErrInfo(E02);
apiWriteLog(0, pstTravelInfo, RET_ERROR);
return;
}
//最后判断路径是否有效
if (RET_ERROR == IsValidTravel(pstTravelInfo))
{
apiPrintOpStatusInfo(I10, pstTravelInfo->nCardNo, pstTravelInfo->nCardMoney);
return;
}
int nDistance = 0;
int flag = 0;
//计算两个站点之间的距离
flag = opGetDistanceBetweenTwoStation(pstTravelInfo->sInStation ,pstTravelInfo->sOutStation, &nDistance);
if(RET_ERROR == flag)
{
apiPrintOpStatusInfo(I10,pstTravelInfo->nCardNo, pstTravelInfo->nCardMoney);
apiWriteLog(0, pstTravelInfo, RET_ERROR);
return;
}
//计算基本票价
nBasePrice = ComputeBasePrice(nDistance);
//计算扣费票价
nChargePrice = ComputeChargePrice(nBasePrice,pstTravelInfo);
//进行扣费,并将扣费记录写入链表尾
ChargeProcess(nChargePrice, pstTravelInfo);
return ;
}
/*****************************************************************************
函 数 名 : opQueryLogProc
功能描述 : 考生需要实现的接口
完成查询乘车记录日志的功能(详见试题规格说明)
q/Q命令时自动调用该函数
输入参数 : pstQueryCond 日志查询条件
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void opQueryLogProc(QueryCond_ST* pstQueryCond)
{
int nTimeDiff = 0;
if (NULL == pstQueryCond)
{
//apiPrintErrInfo(E99);
return;
}
nTimeDiff = apiTimeDiff(pstQueryCond->nStartHour,pstQueryCond->nStartMinute,
pstQueryCond->nEndHour,pstQueryCond->nEndMinute);
if (nTimeDiff > 0)
{
apiPrintErrInfo(E02);
return;
}
//printf("%d\n", pstQueryCond->nCardNo);
if(CARD_UNVAILD == g_CardStatusInfo[pstQueryCond->nCardNo])
{
apiPrintErrInfo(E22);
return;
}
queryLogInf(pstQueryCond);
return;
}
/*****************************************************************************
函 数 名 : opQueryHistoryChargeListProc
功能描述 : 考生需要实现的接口
完成查询指定卡号的票卡消费历史记录功能(详见试题规格说明)
输入参数 : iCardNo 待查询的票卡卡号
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void opQueryHistoryChargeListProc(int iCardNo)
{
HistoryItem *p1 = pHeadHistory;
if (pHeadHistory == NULL)
{
apiPrintErrInfo(E21);
return;
}
if (g_CardStatusInfo[iCardNo] == CARD_UNVAILD)
{
apiPrintErrInfo(E22);
return;
}
if (0 == iCardNo)
{
while(p1 != NULL)
{
apiPrintHistoryChargeList(p1);
writeFile(p1);
p1 = p1->pNextHistory;
}
}
else
searchHistoryNode(iCardNo);
fclose(pfWrite);
}
/*****************************************************************************
函 数 名 : opDestroyCardProc
功能描述 : 考生需要实现的接口
完成注销指定卡号的票卡消费历史记录功能(详见试题规格说明)
输入参数 : iCardNo 待注销的票卡卡号
输出参数 : 无
返 回 值 : 无
*****************************************************************************/
void opDestroyCardProc(int iCardNo)
{
int i = 0;
if ((iCardNo < 0) || (iCardNo > 9))
{
apiPrintErrInfo(E99);
return;
}
if ((0 == iCardNo) && (g_CardStatusInfo[0] == CARD_VALID))
{
for(i = 0; i < MAX_MEMBER_NUM; i++)
{
g_CardStatusInfo[i] = CARD_UNVAILD; //卡号为1-9的不可用
}
apiPrintOpStatusInfo(I22, 0, 0);
removeHistoryList();
}
else
{
if (g_CardStatusInfo[iCardNo] == CARD_VALID)
{
g_CardStatusInfo[iCardNo] = CARD_UNVAILD;
apiPrintOpStatusInfo(I22, iCardNo, 0);
removeNodeByCardNo(iCardNo);
}
else
{
apiPrintErrInfo(E22);
return;
}
}
}
/*其他函数定义考生根据功能需要补充*/
void readFile(void)
{
STA_INFO_S *p1, *p2;
FILE *pf = NULL;
char station[4];
int distance;
//打开读取
pf = fopen("d:\\station_info.txt", "r");
pfWrite = fopen("d:\\SubwayCharge.txt", "w");
if (NULL == pf)
{
printf("error");
return;
}
while(EOF != fscanf(pf, "%s %d\n", station, &distance))
{
p1 = (STA_INFO_S *)malloc(sizeof(STA_INFO_S));
strcpy(p1->sStation, station);
p1->dist = distance;
if (NULL == g_StationList)
{
g_StationList = p1;
p2 = p1;
}
else
{
p2->pNextStation = p1;
p2 = p1;
}
p2->pNextStation = NULL;
}
/*q = g_StationList;
while (q)
{
printf("%s %d\n", q->sStation, q->dist);
q = q->pNextStation;
};*/
fclose(pf);
}
void writeFile(HistoryItem *historyFile)
{
char text[100] = {"卡号:"};
char nCardNo[3] = {" "};
char nInHour[4];
char nInMin[4];
char nOutHour[4];
char nOutMin[4];
char nMoney[4];
sprintf(nCardNo, "%d", historyFile->nCardNo);
sprintf(nMoney, "%d", historyFile->nMoney);
sprintf(nInHour, "%d", historyFile->nInHour);
sprintf(nInMin, "%d", historyFile->nInMin);
sprintf(nOutHour, "%d", historyFile->nOutHour);
sprintf(nOutMin, "%d", historyFile->nOutMin);
strcat(text, nCardNo);
switch(historyFile->enCardType)
{
case CARDTYPE_A: strcat(text, " 卡类别:单程表 进站时间:"); break;
case CARDTYPE_B: strcat(text, " 卡类别:老年卡 进站时间:"); break;
case CARDTYPE_C: strcat(text, " 卡类别:普通卡 进站时间:"); break;
}
strcat(text, nInHour);
strcat(text, ":");
if ((historyFile->nInMin < 10) || ((historyFile->nInMin)%10 == 0))
strcat(text, "0");
strcat(text, nInMin);
strcat(text, " 进站名称:");
strcat(text, historyFile->sInStation);
strcat(text, " 出站时间:");
strcat(text, nOutHour);
strcat(text, ":");
if((historyFile->nOutMin < 10) || ((historyFile->nOutMin)%10 == 0))
strcat(text, "0");
strcat(text, nInMin);
strcat(text, " 出站名称:");
strcat(text, historyFile->sOutStation);
strcat(text, "\n");
printf("%d", strlen(text));
fputs(text, pfWrite);
}
int IsValidTravel(TravelInfo_ST* pstTravelInfo)
{
int i = 0;
STA_INFO_S *p1 = g_StationList;
if (p1 == NULL)
{
apiPrintErrInfo(E99);
return RET_ERROR;
}
for (p1 = g_StationList; p1 != NULL; p1 = p1->pNextStation)
{
if(!strcmp(p1->sStation, pstTravelInfo->sInStation))
{
i = 1;
break;
}
}
for (p1 = g_StationList; p1 != NULL; p1 = p1->pNextStation)
{
if(!strcmp(p1->sStation, pstTravelInfo->sOutStation) && (i = 1))
{
return RET_OK;
}
}
return RET_ERROR;
}
int opGetDistanceBetweenTwoStation(char* sStartStation, char* sObjectStation, int* pnDistance)
{
STA_INFO_S *p1 = NULL;
int startDis = 0, objDis = 0;
if (g_StationList == NULL)
{
printf("error");
return RET_ERROR;
}
for (p1 = g_StationList; p1 != NULL; p1 = p1->pNextStation)
{
if (!strcmp(sStartStation, p1->sStation))
startDis = p1->dist;
if (!strcmp(sObjectStation, p1->sStation))
objDis = p1->dist;
}
*pnDistance = abs(startDis-objDis);
return RET_OK;
}
//计算基本票价
int ComputeBasePrice(int distance)
{
if (0 >= distance)
{
return 0;
}
else if ((0 < distance) && (3 >= distance))
{
return 2;
}
else if ((3 < distance) && (5 >= distance))
{
return 3;
}
else if ((5 < distance) && (10 >= distance))
{
return 4;
}
else
{
return 5;
}
}
//计算扣费票价
int ComputeChargePrice(int baseprice, TravelInfo_ST* pstTravelInfo)
{
int nInHour = 0;
int nInMin = 0;
int nCmpWith07_00 = 0;
int nCmpWith09_00 = 0;
int nCmpWith16_30 = 0;
int nCmpWith18_30 = 0;
int nCmpWith10_00 = 0;
int nCmpWith11_00 = 0;
int nCmpWith15_00 = 0;
int nCmpWith16_00 = 0;
//同站进出
if(0 == strcmp(pstTravelInfo->sInStation, pstTravelInfo->sOutStation))
{
return GetSameStationChargePrice(pstTravelInfo);
}
//非同站进出
else
{
//票卡为单程票
if(CARDTYPE_A == pstTravelInfo->enCardType)
{
return (pstTravelInfo->nCardMoney > baseprice) ? pstTravelInfo->nCardMoney : baseprice;
}
//票卡为非单程票
else
{
nInHour = pstTravelInfo->nInHour;
nInMin = pstTravelInfo->nInMinute;
nCmpWith07_00 = apiTimeDiff(nInHour, nInMin, 7, 0);
nCmpWith09_00 = apiTimeDiff(nInHour, nInMin, 9, 0);
nCmpWith16_30 = apiTimeDiff(nInHour, nInMin, 16, 30);
nCmpWith18_30 = apiTimeDiff(nInHour, nInMin, 18, 30);
if (((0 <= nCmpWith07_00) && (0 > nCmpWith09_00))
|| ((0 <= nCmpWith16_30) && (0 > nCmpWith18_30)))//处于非优惠时段
{
return baseprice;
}
else
{
nCmpWith10_00 = apiTimeDiff(nInHour, nInMin, 10, 0);
nCmpWith11_00 = apiTimeDiff(nInHour, nInMin, 11, 0);
nCmpWith15_00 = apiTimeDiff(nInHour, nInMin, 15, 0);
nCmpWith16_00 = apiTimeDiff(nInHour, nInMin, 16, 0);
if (((0 <= nCmpWith10_00) && (0 > nCmpWith11_00))
|| ((0 <= nCmpWith15_00) && (0 > nCmpWith16_00))) // 处于优惠时段
{
return baseprice/2;
}
else
{
if(CARDTYPE_C == pstTravelInfo->enCardType)
{
return baseprice;
}
else if(CARDTYPE_B == pstTravelInfo->enCardType)
{
return (baseprice*9)/10;
}
}
}
}
}
return 0;
}
//计算同站进出的情况
int GetSameStationChargePrice(TravelInfo_ST* pstTravelInfo)
{
// if(NULL == pstTravelInfo)
int nMoney = 0;
int nTimeDiff = 0;
CardType_EN nCardType;
nMoney = pstTravelInfo->nCardMoney; //卡金额
nCardType= pstTravelInfo->enCardType;
nTimeDiff = apiTimeDiff(pstTravelInfo->nOutHour, pstTravelInfo->nOutMinute, pstTravelInfo->nInHour, pstTravelInfo->nInMinute);
if(nTimeDiff <= 30)
{
if(CARDTYPE_A == nCardType) //单程票
return nMoney;
else
return 0;
}
else
{
if(CARDTYPE_A == nCardType) //单程票
{
return (nMoney>3 ? nMoney:3);
}
else
{
return 3;
}
}
// return 0;
}
int ChargeProcess(int nChargePrice, TravelInfo_ST* pstTravelInfo)
{
int nCardID = pstTravelInfo->nCardNo;
int nLogItems = apiGetLogNum();
//判断扣费票价是否大于卡上余额
if(nChargePrice > pstTravelInfo->nCardMoney)
{
apiPrintOpStatusInfo(I13,nCardID, pstTravelInfo->nCardMoney);
apiWriteLog(0,pstTravelInfo,RET_ERROR);
return RET_ERROR;
}
//计算出消费完成之后的余额
pstTravelInfo->nCardMoney = pstTravelInfo->nCardMoney - nChargePrice;
//如果是单程票
if(CARDTYPE_A == pstTravelInfo->enCardType)
{
apiPrintOpStatusInfo(I11, nCardID, pstTravelInfo->nCardMoney);
}
//非单程票
else
{
if(pstTravelInfo->nCardMoney >= 20)
{
apiPrintOpStatusInfo(I11, pstTravelInfo->nCardNo, pstTravelInfo->nCardMoney);
}
//若果卡内余额小于20的情况,做出提醒
else
{
apiPrintOpStatusInfo(I12, pstTravelInfo->nCardNo, pstTravelInfo->nCardMoney);
}
}
//写日志
apiWriteLog(nChargePrice, pstTravelInfo, RET_OK);
//将扣费记录添加到链表尾
if(RET_OK == AddHistoryItemOnListTail(nChargePrice,pstTravelInfo))
{
return RET_OK;
}
else
{
return RET_ERROR;
}
}
void queryLogInf(QueryCond_ST* pstQueryCond)
{
LogItem_ST tmpLogItem[MAX_LOG_RECORD_NUM];
LogItem_ST *pLogAddr;
int i = 0, j = 0;
int nItems = 0;
int nLogItemCnt = 0;
memset(tmpLogItem, 0, sizeof(LogItem_ST) * MAX_LOG_RECORD_NUM);
pLogAddr = apiGetLogAddr();
nItems = apiGetLogNum();
if (0 == pstQueryCond->nCardNo)
{
for(i = 1; i < MAX_LOG_RECORD_NUM; i++)
{
if(CARD_VALID == g_CardStatusInfo[i])
{
for(j = 0; j < nItems+1; j++)
{
if((i == pLogAddr[j].nCardNo)
&& (RET_OK == IsCheckTimeValid(pstQueryCond,pLogAddr + j)))
{
memcpy(&(tmpLogItem[nLogItemCnt]),&(pLogAddr[j]),sizeof(LogItem_ST));
nLogItemCnt++;
}
}
}
}
}
else
{
for(j = 0; j < nItems; j++)
{
if((pstQueryCond->nCardNo == pLogAddr[j].nCardNo)
&& (RET_OK == IsCheckTimeValid(pstQueryCond,pLogAddr + j)))
{
memcpy(&(tmpLogItem[nLogItemCnt]), &(pLogAddr[j]), sizeof(LogItem_ST));
nLogItemCnt++;
}
}
}
if(nLogItemCnt <= 0)
{
apiPrintErrInfo(E21);
return;
}
else
{
//根据卡号进行排序
SortByCardID(tmpLogItem, nLogItemCnt);
apiPrintLog(tmpLogItem, nLogItemCnt);
}
return;
}
int IsCheckTimeValid(QueryCond_ST* pstQueryCond, LogItem_ST *logAddr)
{
int nQueryStartHour, nQueryStartMin, nQueryEndHour, nQueryEndMin;
int nLogStartHour, nLogStartMin, nLogEndHour, nLogEndMin;
if(NULL == pstQueryCond || NULL == logAddr)
{
apiPrintErrInfo(E99);
return RET_ERROR;
}
nQueryStartHour = pstQueryCond->nStartHour;
nQueryStartMin = pstQueryCond->nStartMinute;
nQueryEndHour = pstQueryCond->nEndHour;
nQueryEndMin = pstQueryCond->nEndMinute;
nLogStartHour = logAddr->nInHour;
nLogStartMin = logAddr->nInMin;
nLogEndHour = logAddr->nOutHour;
nLogEndMin = logAddr->nOutMin;
if((apiTimeDiff(nQueryStartHour, nQueryStartMin, nLogEndHour, nLogEndMin) <= 0)
&& (apiTimeDiff(nLogEndHour,nLogEndMin,nQueryEndHour,nQueryEndMin) <= 0))
{
return RET_OK;
}
else
{
return RET_ERROR;
}
}
void Swap(LogItem_ST &logItemA, LogItem_ST &logItemB)
{
LogItem_ST tmp;
memcpy(&tmp, &logItemA, sizeof(LogItem_ST));
memcpy(&logItemA, &logItemB, sizeof(LogItem_ST));
memcpy(&logItemB, &tmp, sizeof(LogItem_ST));
}
//利用冒泡排序对卡号进行排序
void SortByCardID(LogItem_ST logItems[], int nItems)
{
if(NULL == logItems || nItems <= 0)
{
return;
}
int i = 0, k = nItems;
int flag = 1;
while(flag)
{
flag = 0;
for (i = 1; i < k; i++)
{
if (logItems[i - 1].nCardNo > logItems[i].nCardNo)
{
Swap(logItems[i - 1], logItems[i]);
flag = 1;
}
}
k--;
}
}
int AddHistoryItemOnListTail(int nChargePrice, TravelInfo_ST* pstTravelInfo)
{
HistoryItem *p1, *p2 = pHeadHistory;
p1 = (HistoryItem *)malloc(sizeof(HistoryItem));
p1->enCardType = pstTravelInfo->enCardType;
p1->nCardNo = pstTravelInfo->nCardNo;
p1->nInHour = pstTravelInfo->nInHour;
p1->nInMin = pstTravelInfo->nInMinute;
strcpy(p1->sInStation, pstTravelInfo->sInStation);
p1->nMoney = nChargePrice;
p1->nOutHour = pstTravelInfo->nOutHour;
p1->nOutMin = pstTravelInfo->nOutMinute;
strcpy(p1->sOutStation, pstTravelInfo->sOutStation);
if (NULL == p1)
{
printf("error");
return RET_ERROR;
}
if (NULL == p2)
{
pHeadHistory = p1;
p1->pNextHistory = NULL;
}
else
{
for (p2 = pHeadHistory; ; p2 = p2->pNextHistory)
{
if (p2->pNextHistory == NULL)
{
p2->pNextHistory = p1;
p1->pNextHistory = NULL;
break;
}
}
}
return RET_OK;
}
HistoryItem *removeNodeByCardNo(int iCradNo)
{
HistoryItem *pNode = NULL;
HistoryItem *pDelNode = NULL;
if ((NULL == pHeadHistory) || (iCradNo < 0))
{
//apiPrintErrInfo(E99);
return NULL;
}
while((iCradNo == pHeadHistory->nCardNo))
{
pDelNode = pHeadHistory;
pHeadHistory = pHeadHistory->pNextHistory;
free(pDelNode);
if(pHeadHistory == NULL)
return NULL;
}
for (pNode = pHeadHistory; pNode->pNextHistory!= NULL; )
{
pDelNode = pNode->pNextHistory;
if (pNode->pNextHistory->nCardNo== iCradNo)
{
if (pNode->pNextHistory->pNextHistory == NULL)
{
pNode->pNextHistory = NULL;
pDelNode = pDelNode->pNextHistory;
free(pDelNode);
break;
}
else
{
pNode->pNextHistory = pDelNode->pNextHistory;
free(pDelNode);
}
}
else
pNode = pNode->pNextHistory;
}
if (NULL == pDelNode)
return NULL;
free(pDelNode);
return pHeadHistory;
}
void removeHistoryList(void)
{
HistoryItem *pNode, *pTemp;
if (NULL == pHeadHistory)
{
return;
}
pNode = pHeadHistory;
pTemp = pNode->pNextHistory;
if (pTemp == NULL)
{
free(pNode);
}
else
{
while(pTemp != NULL)
{
free(pNode);
pNode = pTemp;
pTemp = pTemp->pNextHistory;
}
free(pNode);
}
pNode = NULL;
return;
}
void searchHistoryNode(int iCardNo)
{
int i = 0;
HistoryItem *p1;
if (NULL == pHeadHistory)
{
apiPrintErrInfo(E99);
return;
}
for (p1 = pHeadHistory; p1 != NULL; p1 = p1->pNextHistory)
{
if (p1->nCardNo == iCardNo)
{
apiPrintHistoryChargeList(p1);
writeFile(p1);
i = 1;
}
}
if (0 == i)
apiPrintErrInfo(E21);
return;
}
0 0
- 停车场收费系统
- 停车场收费系统2
- 停车场收费
- 停车场系统
- 百练 2933 停车场收费
- 停车场收费管理的未来发展趋势
- 如何实现停车场自动收费的秘密?
- 停车场管理系统
- 停车场管理系统
- 停车场模拟管理系统
- 课程设计---停车场管理系统
- 停车场管理系统
- 停车场管理系统
- 停车场管理系统
- 停车场管理系统
- 停车场管理系统
- 停车场管理系统
- 模拟停车场管理系统
- 如何实现只允许应用服务器连接mysql
- 文件偏移量与C语言中的流定位
- 这篇文章为了请教大牛帮忙解决一下现网乱码问题
- Maven聚合与继承
- SVN之Linux服务器环境搭建
- 停车场收费系统
- 某时间段内的断点
- hadoop hive mahout
- 瞎折腾系列之linux服务器安装redis
- gem5集成NVMain
- 停车场收费系统2
- hbase与mysql的区别
- Standford CS231n 循环神经网络 简要笔记
- Android学习之Java基础篇day2