CSDN博客

img hongweijin

酒店管理(链表和文件操作)

发表于2004/6/22 21:25:00  1464人阅读

分类: C/C++Learning Notes

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LEN sizeof(GUEST)
#define FILENAME_LEN 10
#define NULL 0
#define FORMAT "/n%20d%20s%20d/n"
#define TRUE 1
#define FALSE 0

struct guest
{
 int number;           /*客号*/
 char name[10];        /*姓名*/
 int money;     /*金额*/
 struct guest *pNext;
};

typedef struct guest GUEST;

/*函数的初始化*/
GUEST *Creat(void);
GUEST *Delect(GUEST *pHeadGet, int numSelect);
GUEST *ReadList(void );

char WelcomeAndTip(void);

void Insert(GUEST *pHeadGet, int numInsert);
void Show(GUEST *pHeadGet);
void Max_Print(GUEST *pHeadGet);
void ListSave(GUEST *pHeadGet);
void FoundAndPrint(GUEST *pHeadGet, int number);
void Update(GUEST *pHeadGet, int number, int newMoney);

/*
===========================
 功能:main,对各个函数进行选择
 返回:void
===========================
*/
void main()
{
 GUEST *pHead = NULL;
 char select;
 int client, number;

SELECT: select = WelcomeAndTip(); /*欢迎界面*/
 switch(select)
 {
 case 'I' :case 'i' :
    if (pHead == NULL)
    {
     pHead = Creat();
     system("cls");
     Show(pHead);
    }
    else
    {
     system("cls");
     printf("/n链表已经从文件读入存在/n");
    }
    break;

 case 'D' :case 'd' :
    system("cls");
    Show(pHead);
    printf("/n请输入您要删除的客号:");
    scanf("%d", &client);
    pHead = Delect(pHead, client);
    system("cls");
    Show(pHead);
    break; 
    
 case 'S' :case 's' :
    printf("请输入您要插入记录的id(不要超过当前链表的长度):");
    scanf("%d", &client);
    Insert(pHead, client);
    system("cls");
    Show(pHead);
    break; 

 case 'Q' :case 'q':
          system("cls");
    Show(pHead);
    break;

 case 'M' :case 'm':
    Max_Print(pHead);
    break;

 case 'B' :case 'b':
    ListSave(pHead);
    break;

 case 'R' :case 'r':
    pHead = ReadList();
    system("cls");
    Show(pHead);
    break;

 case 'F' :case 'f': /*用number作为内部的唯一id,名字会有重名*/
    system("cls");
    Show(pHead);
    printf("/n请输入您要查询的客号:");
    scanf("%d", &client);
    system("cls");
    FoundAndPrint(pHead, client);
    break;

 case 'C':case 'c':
    system("cls");
    Show(pHead);
    printf("/n请输入要宾客的客号和结算金额(用空格隔开):");
    scanf("%d%d", &number, &client);
    system("cls");

    Update(pHead, number, client);
    break;
    
 default  :
    system("pause");
    system("cls");
    printf("/n请重新选择/n");
    break;
 }
 goto SELECT;

}
/*
===========================
 功能:打印开始的欢迎消息和操作提示
 返回:void
 传入:void
===========================
*/
char WelcomeAndTip(void)        /*欢迎和提示界面*/
{
 int client;
 char select;

 printf("/t/t/t    酒店管理(文件操作)/n");
 for( client =0; client < 80; client++)
 {
  printf("=");
 }
 printf("/n");
 printf("I:创建/tD:删除/tQ:显示/tS:插入/tM:最大/tB:保存/tR:读入/tF:查找/tC:结算/n");
 for( client =0; client < 80; client++)
 {
  printf("=");
 }
 printf("/n请输入您要进行的操作:");
 scanf("%c", &select);
 return select;
}
/*
===========================
 功能:输出整个节点
 返回:void
 传入:链表的头指针
===========================
*/
void Show(GUEST *pHeadGet)
{
 GUEST *pClient;
 
 pClient = pHeadGet;

 if(pClient == NULL)
 {
  printf("/n数据为空没有数据可以打印/n");
 }
 else
 {
  printf("/t/t客号/t/t姓名/t/t/t金额");
  do
  {
   printf(FORMAT, pClient->number, pClient->name, pClient->money);
   pClient = pClient->pNext;
  }while(pClient != NULL);
 }
}
/*
=========================================================
 功能:创造整个节点,不对输入的数据进行控制,和错误判断。
 返回:链表头指针
 传入:void
=========================================================
*/
GUEST *Creat(void)
{
 GUEST *pHead = NULL, *pOne = NULL, *pTwo = NULL;
 int numberTemp = 1;
 
 pOne = (GUEST *) malloc(LEN);
 if(pOne == NULL)
 {
  printf("/n开辟不成功请重试/n");
 }
 else
 {
  pTwo = pOne;
  pHead = pOne;
  pTwo->pNext = NULL;
  
  printf("/n请输入第%d个的客号,金额,用空格相隔,以0 0结束输入:", numberTemp);
  scanf("%d%d", &pOne->number, &pOne->money);
  _flushall();
  printf("/n请输入第%d个宾客的名字:  ", numberTemp);
  gets(pOne->name);
  
 }

 while (pOne->number != 0)
 {
  pTwo = pOne;//在开辟之前,前应该给后面的指针赋予前面的指针
  pOne = (GUEST *) malloc(LEN);
  numberTemp++;
  
  printf("/n请输入第%d个的客号,金额,用空格相隔:", numberTemp);
  scanf("%d%d", &pOne->number, &pOne->money);
  _flushall();
  printf("/n请输入第%d个宾客的名字:  ", numberTemp);
  gets(pOne->name);
  
  pTwo->pNext = pOne;
 }
 pTwo->pNext = NULL;
 free(pOne);
 pOne = NULL;
 // free(pTwo); 空间没有开辟,何来释放
 // pTwo = NULL;
 return(pHead);
 }
/*
======================================
 功能:删除指定客号的节点
 返回:void
 传入:链表的头指针和要删除的结点次序
======================================
*/
GUEST *Delect(GUEST *pHeadGet, int numSelect)
{
 GUEST *pOne = NULL, *pTwo = NULL;

 pOne = pHeadGet;
 
 if (pHeadGet == NULL)
 {
  printf("/n数据为空没有数据可以删除/n");
 }
 else
 {
  while( (pOne->number != numSelect) && (pOne->pNext != NULL) )
  {
   pTwo = pOne;
   pOne = pOne->pNext;
  
  }
  if( numSelect == pOne->number )
  {
   if(pOne == pHeadGet)
   {
    pHeadGet = pOne->pNext;
    free(pOne);
   }
   else
   {
    pTwo->pNext = pOne->pNext;
    free(pOne);
   }
  }
  else
  {
   printf("/n没有找到要删除的宾客:/n");
  }
 }
 return pHeadGet;  /*若数据位于头节需要返回头一节*/
}

/*
===========================
 功能: 查找制定客号的数据
 返回:void
 传入:pHead(头指针), number(客号)
===========================
*/
void FoundAndPrint(GUEST *pHeadGet, int number)
{
 GUEST *pClient = NULL;
 int temp = FALSE;
 
 pClient = pHeadGet;
 
 if(pClient == NULL)
 {
  printf("/n数据为空没有数据可以查找/n");
 }
 else
 { 
  while(pClient != NULL)
  {
   if (number == pClient->number)
   {
    printf("/t/t客号/t/t姓名/t/t/t金额");
    printf(FORMAT, pClient->number, pClient->name, pClient->money); 
    temp = TRUE;
    break;
   }
   pClient = pClient->pNext;
  
  }
  if (!temp)
  {
   printf("/n没有找到您要的数据,请核实!/n");
  }
 }
}

/*
===========================
 功能:指定处(数据的那一条的后面)插入节点
 返回:void
 传入:链表的头指针和插入的位置
===========================
*/
void Insert(GUEST *pHeadGet, int numInsert)
{
 GUEST *pOne = NULL, *pTwo = NULL, *pInsert = NULL;
 int temp;

 pTwo = pOne = pHeadGet;
 /*这里的算法很糟糕,怎样快速定位指定的节点?*/
 for( temp = 1; temp < numInsert; temp++ )
 {
  pTwo = pTwo->pNext;
 }
 pOne = pTwo->pNext;
    pInsert = (GUEST *) malloc(LEN);
 
 printf("/n请输入该客号,金额,用空格相隔:");
 scanf("%d%d", &pInsert->number, &pInsert->money);
 _flushall();
 printf("/n请输入插入宾客名字:  ");
 gets(pInsert->name);
 
 pTwo->pNext    = pInsert;
 pInsert->pNext = pOne;
}
/*
===========================
功能:找到最大的消费金额的宾客数据并打印
返回:void
传入:链表的头指针
===========================
*/
void Max_Print(GUEST *pHeadGet)
{
 int max;
 GUEST *pScan = NULL, *pPut = NULL;

 if (pHeadGet == NULL)
 {
  printf("/n数据为空没有数据可以比较/n");
 }
 else
 {
  max = pHeadGet->money;
  pScan = pHeadGet->pNext;
  pPut = pHeadGet; /*初始化打印节点*/
  if(pScan != NULL) /*判断是不是为一个节点的链表*/
  {
   do
   {
    if(pScan->money > max)
    {
     max = pScan->money;
     pPut = pScan;
    }
    else
    {
     pPut = pHeadGet;
    }
    pScan = pScan->pNext;
   } while(pScan != NULL);
  }
  system("cls");
  printf("金额最好的宾客:/n");
  printf("/t/t客号/t/t姓名/t/t/t金额");
  printf(FORMAT, pPut->number, pPut->name, pPut->money);
 }
}

/*
============================================================
功能:更新客户当前的消费。
   当一个客户消费时,若累积消费总金额大于10000万元,
      此次就打6折,大于5000万元,打8折;大于1000 元,打9折,
      并更新文件中此客户的消费总金额。
返回:void
传入:pHead(链表的头指针),number(客号),newMoney(最新消费)
============================================================
*/

void Update(GUEST *pHeadGet, int number, int newMoney)
{
 GUEST *pClient = NULL;
 int temp = FALSE;
 
 pClient = pHeadGet;
 
 if(pClient == NULL)
 {
  printf("/n数据为空没有数据可以更新的/n");
 }
 else
 { 
  while(pClient != NULL)
  {
   if (number == pClient->number)
   {
    if(pClient->money > 10000)
     printf("/n这位宾客需要付款:%d/n", (int)(newMoney * 0.6));
    else if ((pClient->money < 10000) && (pClient->money > 5000))
     printf("/n这位宾客需要付款:%d/n", (int)(newMoney * 0.8));
    else
     printf("/n这位宾客需要付款:%d/n", newMoney);
    
    pClient->money += newMoney;
    temp = TRUE;
    break;
   }
   pClient = pClient->pNext;
   
  }
  if (!temp)
  {
   printf("/n没有找到您要更新的数据项,请核实!/n");
  }
 }
}

/*
===========================
功能:保存当前链表为文件
返回:void
传入:链表的头指针
===========================
*/

void ListSave(GUEST *pHeadGet)
{
 FILE *fposition = NULL;
 char fileName[FILENAME_LEN];
 GUEST *pOne = pHeadGet;
 int listLen = 0;
  
 if (pHeadGet == NULL)
 {
  printf("/n数据为空没有数据可以保存/n");
 }
 else
 {
  while (pOne)
  {
   pOne = pOne ->pNext;
   listLen++;
  } /*得到链表的长度*/

  printf("/n请输入文件名,以txt方式(*.txt):");
  _flushall();
  gets(fileName);
  if ((fposition = fopen (fileName, "w")) == NULL)
  {
   printf("/n打开文件失败/n");
   exit(0);
  }
  pOne = pHeadGet;
//  fprintf(fposition, "/t/t客号/t/t姓名/t/t/t金额");
  while (pOne != NULL)
  {
   if (! fprintf(fposition, FORMAT, pOne->number,pOne->name, pOne->money))
   {
    printf("/n读入文件出错/n");
   }
   pOne = pOne->pNext;
  }
  fclose(fposition);
  
 }
}

/*
===========================
功能:读入文件并创建为当前链表
返回:pHead
传入:void
===========================
*/
GUEST *ReadList(void)
{
 FILE *fposition = NULL;
 char fileName[FILENAME_LEN];
 GUEST *pOne = NULL, *pTwo = NULL, *pHead = NULL;

 printf("/n请输入您要打开的文件名,以txt方式(*.txt):");
 _flushall();
 gets(fileName);
 
 if ((fposition = fopen (fileName, "r")) == NULL)
 {
  printf("/n打开文件失败/n");
  exit(0);
 }

 pOne = (GUEST *) malloc(LEN);
 pTwo = pOne;
 pHead = pOne;
 pHead->pNext = NULL;
 
// fseek(fposition, (long)60L, 0); 
 while (!feof(fposition))
 {
  if (!fscanf(fposition, FORMAT, &pOne->number, &pOne->name, &pOne->money))
   printf("/n读入文件出错,可能文件为空,或文件不存在!/n");
  
  pTwo = pOne;
  pOne = (GUEST *) malloc(LEN);
  pTwo->pNext = pOne;
  
 }
 pTwo->pNext = NULL;
 free(pOne); /*释放多余的创建*/
 pOne = NULL;
 return pHead;
}

0 0

相关博文

我的热门文章

img
取 消
img