家庭财务管理系统源代码

 

//money.h
#ifndef money_h
#define money_h
#include "string"
using namespace std;

class Common       //提供常用功能的类:Common
{
public:
  inline void beep();     //代码行数在1到5行之间的,定义为inline(内联)函数可以提高效率
  static void println(const string IM,int count_enter);     //输出指定的字符串和回车,默认回车数为1
  static void stay(int v);   //函数功能stay:通过耗时的for循环,让程序暂停一段时间
  static void pause();     //静态函数pause:输出让用户等待的消息,然后让程序暂停,直到用户有按键动作
  static void clear();     //静态函数clear:清除屏幕
//下面的函数不是静态函数,需要通过“对象名.函数名”来调用
  void backcolor();
  void WordByWord(const char *infor,int v);   //将字符串中的各个字符逐个输出出来
  void showMySplash();                  //显示本程序的版权信息
  char login();       //显示登录界面
  char showMyMenu();     //显示菜单界面
};

class entry        //封装用户登录信息类:entry
{
public:
 string ID;       //用户ID号
 string key;       //用户密码
 string ft_name;
 string fh_name;
  entry();        //构造函数1
  entry(string id,string k);   //构造函数2
  string &filename();     //系统为该用户生成的文件名,没个用户有自己的文件,实现信息的独立性
  string &htmlname();     //为生成的网页文件提供文件名
  bool password(string id,string k); //密码验证函数,返回一个bool量
  char setkey();      //密码设置函数
};

class Node_entry      //结构体Node封装两项信息:要存储的数据,下一个节点内存地址,用于制作链表。     
{
public:
  entry objentry;
  Node_entry *next;
  Node_entry(entry& objtemp,Node_entry *p);//构造函数
};

class AccountList
{
private:
  Node_entry *head,*p,*q;    //定义三个指针,指向链表的头,当前节点,前驱节点
public:
  AccountList();      //构造
  ~AccountList();      //析构函数,构造时接收两个参数:要存储的数据,下一个节点内存地址
  void desNode();      //析构后释放节点的内存
  void addNode_entry(entry &obj);  //添加节点,每次都添加在首位即可……
  bool queryNode_entry(entry  &obj); //查找节点
  int count();       //计算节点数目
  Node_entry * vali_key();      //验证密码
  void savepassword(const char *fileName);  //保存用户信息到文件
  void loadpassword(const char *fileName);  //从文件读取信息
};

class timedata       //封装时间的类
{
public:
  int day,month,year;     //定义三个共有成员数据,方便提取和赋值,(int)日、月、年

  timedata();       //构造函数1
  timedata(int da,int mo,int yr);  //构造函数2
  bool operator < (timedata d2);  //运算符重载“<”
  bool operator > (timedata d2);  //运算符重载“>”
  bool operator == (timedata d2);  //运算符重载“==”
  bool operator != (timedata d2);  //运算符重载“!=”
  bool operator <= (timedata d2);  //运算符重载“<=”
  bool operator >= (timedata d2);  //运算符重载“>=”
  timedata operator = (timedata d2); //运算符重载“=”
  void showdate();      //输出类中的成员变量
  static  timedata read_date(string &src); //读取string型的时间(如2009.6.15),赋值到day,month,year
};

class money        //封装数据的类:money
{
public:
  //支出项
  timedata date;         //日期
  double rate_WEG;        //水电煤气费
  double rate_phone;      //电话费
  double rate_school;     //学杂费
  double rate_living;     //生活费
  double rate_other;      //其他项支出
  double rate_all;      //总支出
  //收入项
  double income_pay;                 //工资
  double income_lay;                 //金融投资所得
  double income_interest;         //存款利息
  double income_other;       //其他项收取
  double income_all;     //总收取
  money();
  //构造函数
  money(int da,int mo,int yr,double WEG,double phone,double school,double living,double r_other,double pay,double lay,double interest,double i_other);
  void inString();      //输入类的成员变量
  void toString();      //输出类中的成员变量
};

class Node        //结构体Node封装两项信息:要存储的数据,下一个节点内存地址,用于制作链表。
{
public:
  money objData;
  Node *NEXT;
  Node(money& objArg,Node *nArg);  //构造时接收两个参数:要存储的数据,下一个节点内存地址
};

class MyList       //单链表类:MyList
{
private:
  Node *START,*CURR,*PREV;    //定义三个指针,指向链表的头,当前节点,前驱节点
  money splitStr(string &src, string  &delim); //定义一个私有函数,将字符串拆分为多个部分,存储到money类的对象中
public:
  //构造函数、析构函数、销毁对象的函数
  MyList();
  ~MyList();
  void destroy();
  //添加节点、删除节点、查询节点、遍历节点的函数
  void addNode(money &obj);
  bool delNode(money &obj);
  bool queryNode(money  &obj);
  void viewAllNodes();
  //返回节点数量的函数
  int size();
  //以下六个函数,是为了完成特定操作,在本链表类中新增的
  void loadFromTxtFile(const char *fileName,entry obj);
  void saveToTxtFile(const char *fileName);
  void writeToBinFile(const char *fileName);
  void exportToHtmlFile(const char *fileName);
  void Avy_all();
  void findBydate(timedata d1,timedata d2);
};

#endif

//money.cpp
#include "iostream"      //输入输出用到"iostream"
#include "fstream"      //文件操作用到"fstream"
#include "iomanip"      //setw和setfill格式化输出用到"iomanip"
#include "string"      //字符串用到"string"
#include "conio.h"      //getch需用到"conio.h"
#include "money.h"
using namespace std;

const  int  MAXSIZE=1024;     //假设文本文件的一行最多有1024个字符
const  int  money_COLS=12;     //定义要导入的文本文件中每行数据的列数
const  int  NUMS_PER_PAGE=4;     //查询的时候,每显示4项信息,产生一个换行

const  char  *KEY_FILE="Account.secret";   //文本文件的名称

inline void Common::beep()
  {
    cout<<'/a';       //转义符/a表示响铃
  }//end of beep()

void Common::println(const string IM,int count_enter=1)  //输出指定的字符串和回车,默认回车数为1
  {
    cout<<IM;
    for(int i=1;i<=count_enter;i++) cout<<endl;
  }//end of println()

void Common::stay(int v=40)                  //函数功能stay:通过耗时的for循环,让程序暂停一段时间
  { v=v*1000000;
    for(int i=1;i<=v;i++);
  }//end of stay()

void Common::pause()                //静态函数pause:输出让用户等待的消息,然后让程序暂停,直到用户有按键动作
  {
    cout<<"            ---------------------按下任意键继续---------------------";
    getch();
    clear();    
    cout<<endl;
  }//end of pause()

void Common::clear()                //静态函数clear:清除屏幕
  {
   system("cls");
  }//end of clear()

void Common::backcolor()
  {char B;
   char W;
   string s_color="color ";
   cout<<endl<<endl<<endl;
   cout<<"                                  个性化设置"<<endl<<endl;
   cout<<"                           请选择您要使用的背景颜色"<<endl<<endl;
   cout<<"                             0.黑色      8.灰色"<<endl;
   cout<<"                             1.蓝色      9.灰蓝色"<<endl;
   cout<<"                             2.绿色      A.淡绿色"<<endl;
   cout<<"                             3.湖蓝色    B.淡浅绿色"<<endl;
   cout<<"                             4.红色      C.淡红色"<<endl;
   cout<<"                             5.紫色      D.淡紫色"<<endl;
   cout<<"                             6.黄色      E.淡黄色"<<endl;
   cout<<"                             7.白色      F.亮白色"<<endl;
   B=getch();
   beep();
   clear();
   s_color.append( 1, B );
   cout<<endl<<endl<<endl;
   cout<<"                                  个性化设置"<<endl<<endl;
   cout<<"                           请选择您要使用的字体颜色"<<endl<<endl;
   cout<<"                             0.黑色      8.灰色  "<<endl;
   cout<<"                             1.蓝色      9.灰蓝色  "<<endl;
   cout<<"                             2.绿色      A.淡绿色  "<<endl;
   cout<<"                             3.湖蓝色    B.淡浅绿色 "<<endl;
   cout<<"                             4.红色      C.淡红色  "<<endl;
   cout<<"                             5.紫色      D.淡紫色  "<<endl;
   cout<<"                             6.黄色      E.淡黄色  "<<endl;
   cout<<"                             7.白色      F.亮白色  "<<endl;  
   W=getch();
   beep();
   s_color.append( 1, W );
   cout<<"                    主题设置成功,下面进入系统,祝您使用愉快!"<<endl;
   pause();
   system(s_color.c_str());
  }

void Common::WordByWord(const char *infor,int v=40)   //将字符串中的各个字符逐个输出出来
  {
    //检测参数的有效性
    int count_word=strlen(infor);
    if (count_word<1) return;
    //产生声音
    beep();
    //每次取出一个字符输出出来,然后暂停一段时间
    for(int i=0;i<count_word;i++)
    {
      cout<<*(infor+i);               //每次取出一个字符
      cout<<flush;                  //立即刷新缓冲区(确保当前的字符立即输出到屏幕)
      stay(v);
    }//end of for
    cout<<endl;
    beep();
  }//end of WordByWord(const sting infor)

void Common::showMySplash()                  //显示本程序的版权信息
  {
    println(" ",7);      //产生7个回车
  WordByWord("                              家庭财务管理系统");
 cout<<endl;
    println("                   计算机科学与技术系   08级计本二班 殷伟峰",3);
  }//end of showMySplash()

char Common::login()
  {
    char a;
  WordByWord("      ---------------------欢迎使用家庭财务管理系统---------------------",7);
  println("                              我们将竭诚为您服务",4);
  println("                                    1.登录");
  println("                                    2.注册");
  println("                                    3.退出",3);
  println("      *******************************************************************");
     println("     【温馨提示】:为了保证您的信息安全,请选择登录,并输入您的帐号和密码,");
     println("      如果您还没有注册,请选择注册,谢谢,如有疑问,请及时与我们取得联系。");
     println("                                 QQ:390555787  ");
     println("                                TEL:13856023611  ");
     println("                           EMAIL:ywf1990@hatmail.com  ");
  println("      *******************************************************************");
     a=getch();
  beep();
  clear();
  return a;
  }


char Common::showMyMenu()
  {
 char b;
    cout<<endl;
 println("      ---------------------欢迎登陆家庭财务管理系统---------------------",2);
 println("                              我们将竭诚为您服务",4);
 println("                          ︻┳═一程序主菜单─═┳︻  ",2);
 println("                                1.添加新的信息");
 println("                                2.查看历史记录");
    println("                                3.删除历史信息");
    println("                                4.修改历史信息");
 println("                                5.综合财务管理");
 println("                                6.保存信息");
 println("                                7.退出系统",3);

 println("      *******************************************************************");
 println("      -------------如在使用过程中发现问题,请及时与我们联系--------------");
    println("                                 QQ:390555787  ");
    println("                                TEL:13856023611  ");
    println("                           EMAIL:ywf1990@hatmail.com  ");
 println("      *******************************************************************");
    b=getch();
 clear();
 beep();
 return b;
   }

entry::entry() {}

entry::entry(string id,string k)
  {
    ID=id;
 key=k;
  }

string & entry::filename()
  { ft_name=ID;
    ft_name.append(".txt" );
 return ft_name;
  }

string &entry::htmlname()
  { fh_name=ID;
    fh_name.append(".html" );
 return fh_name;
  }

bool entry::password(string id,string k)
  {
    if(ID==id&&key==k) return true;
 else return false;
  }

char entry::setkey()
  {  char c;
     string A;
  string B;

  for(;;)
  {char t;
   char u;
  cout<<endl<<endl<<endl;
  cout<<"      ---------------------欢迎使用家庭财务管理系统---------------------"<<endl;    
  cout<<"                      下面进入注册,请您耐心看完提示信息!"<<endl<<endl<<endl<<endl;

  cout<<"      ︻┳═一 请输入您的注册ID(可以是任意16位以内的字符串):";
  cin>>ID;
  cout<<"      ︻┳═一 请输入您的注册密码(不超过16位,以空格结束):";
  for(int i=1;i<=17;i++)
  {
  t=getch();
  if(t==13) break;
  cout<<'*';
     A.append(1,t);
  }
  cout<<endl<<"               请重新输入密码,以便确认:";
  for(int j=1;j<=17;j++)
  {
  u=getch();
     if(u==13) break;
  cout<<'*';
     B.append(1,u);
  }
  if(A==B) {key=A;break;}
  else cout<<endl<<"                         两次输入密码不同,请重新注册!";
  }//end of for

  system("cls");
  cout<<endl<<endl<<endl<<endl<<endl<<endl<<endl;
  cout<<"                              注册成功,现在登录?"<<endl;
  cout<<"                                    Y:登陆"<<endl;
  cout<<"                                    N:退出"<<endl;
  c=getch();
  system("cls");
 return c;
  }//end of setkey

Node_entry::Node_entry(entry& objtemp,Node_entry *p=NULL)
  {
    objentry=objtemp;
    next=p;
  }//end of 构造

AccountList::AccountList()   //构造
  { head=p=q=NULL;}

AccountList::~AccountList()  { desNode();}  //析构

void AccountList::desNode()
  {
    while(head!=NULL)
 {
    p=head;
    head=head->next;
    delete p;
 }//end while
    head=p=q=NULL;
  }

void AccountList::addNode_entry(entry &obj)  //每次都添加在首位即可……
  {
    head=new Node_entry(obj,head);
  }

bool AccountList::queryNode_entry(entry  &obj)   //查找,将class AccountList的成员变量p指向查找量……
  {
  p=q=head;
  while(p!=NULL && obj.ID!= p->objentry.ID) {q=p,p=p->next;}
  return  (p!=NULL);
  }

int AccountList::count()
  {
  int n=0;
  Node_entry *temp=head;
  while(temp!=NULL)
  { temp=temp->next;
    n++;
  }
  return n;
  }

Node_entry * AccountList::vali_key()
  { char u;
 string id; //记录输入的ID
 string ky; //记录输入的key
 for(int i=0;;i++)   //无限循环,控制密码输入,正确时退出,3次错误自动退出
 {
 cout<<endl<<endl<<endl;
 cout<<"                            家庭财务管理系统登陆"<<endl<<endl;
 cout<<"                      ︻┳═一 请输入您的ID:";
 cin>>id;
 cout<<"                      ︻┳═一 请输入您的密码(以空格结束):";
  for(int j=1;j<=17;j++)
  {
  u=getch();
     if(u==13) break;
  cout<<'*';
     ky.append(1,u);
  }
 entry temp(id,ky);
 if(queryNode_entry(temp)){if(p->objentry.key==ky) break;}

 system("cls");
 if(i==2) exit(0);
 cout<<endl<<endl<<"               ID或密码错误!"; 
 }//end for 
 cout<<endl<<endl<<endl<<endl<<endl<<endl<<endl<<endl;
 cout<<"                           登陆成功,祝您使用愉快!"<<endl<<endl<<endl<<endl;
 cout<<"正在进入系统";
    for(int j=0;j<6;j++)
    {
      cout<<".";               //每次取出一个字符
      cout<<flush;                  //立即刷新缓冲区(确保当前的字符立即输出到屏幕)
      for(int k=1;k<=80000000;k++);
    }
    cout<<endl;
    system("cls");
    return p;
  }//end of vali_key

void AccountList::savepassword(const char *fileName)
  {
  if (count()==0)
  {
  return;
  }
  ofstream f1(fileName);
  if(!f1)  exit(-1);
  for(Node_entry *T=head;T!=NULL;T=T->next)
  {
    f1<<T->objentry.ID<<"/t"<<T->objentry.key<<endl;
  }//end of for
  f1.close();  
  }

void AccountList::loadpassword(const char *fileName)
  {
  entry T_entry;
  ifstream f2(fileName);
  if(!f2)
  exit(-1);
  while(f2.good())
  {   
   f2>>T_entry.ID>>T_entry.key;
   addNode_entry( T_entry );
  }
  f2.close();
  }

timedata::timedata()
  {
    day=28;
    month=6;
    year=2009;
  }//end of 构造1

timedata::timedata(int da,int mo,int yr)
  {
    day=da;
    month=mo;
    year=yr;
  }//end of 构造2

bool timedata::operator < (timedata d2)
  {
    if(year-d2.year<0) return true;
    if(year-d2.year==0&&month-d2.month<0) return true;
    if(year-d2.year==0&&month-d2.month==0&&day-d2.day<0) return true;
    else return false;
  }

bool timedata::operator > (timedata d2)
  {
    if(year-d2.year>0) return true;
    if(year-d2.year==0&&month-d2.month>0) return true;
    if(year-d2.year==0&&month-d2.month==0&&day-d2.day>0) return true;
    else return false;
  }

bool timedata::operator == (timedata d2)
  {
    if(year-d2.year==0&&month-d2.month==0&&day-d2.day==0) return true;
    else return false;
  }

bool timedata::operator != (timedata d2)
  {
    if(year-d2.year==0&&month-d2.month==0&&day-d2.day==0) return false;
    else return true;
  }

bool timedata::operator <= (timedata d2)
  {
    if(year-d2.year<0) return true;
    if(year-d2.year==0&&month-d2.month<0) return true;
    if(year-d2.year==0&&month-d2.month==0&&day-d2.day<=0) return true;
    else return false;
  }

bool timedata::operator >= (timedata d2)
  {
    if(year-d2.year>0) return true;
    if(year-d2.year==0&&month-d2.month>0) return true;
    if(year-d2.year==0&&month-d2.month==0&&day-d2.day>=0) return true;
    else return false;
  }

timedata timedata::operator = (timedata d2)
  {
    return timedata(year=d2.year,month=d2.month,day=d2.day);
  }

void timedata::showdate()  //输出类中的成员变量
  {
    cout<<year<<'.'<<month<<'.'<<day;
   }

timedata timedata::read_date(string &src)
  {
    timedata obj;
 string s=".";
    int iOFF=s.length();
    int a=src.find(s,0);
    int b=src.find(s,a+1);
    string yr=src.substr(0,a);
    string mo=src.substr(a+iOFF,b-a-iOFF);
    string da=src.substr(b+iOFF);
    obj.month=atoi(mo.c_str());      
    obj.day=atoi(da.c_str());    
    return obj;
  }

money::money(){}
money::money(int da,int mo,int yr,double WEG,double phone,double school,double living,double r_other,double pay,double lay,double interest,double

i_other):date(da,mo,yr)
  {  
  rate_WEG=WEG;      
  rate_phone=phone;    
  rate_school=school;   
  rate_living=living;   
  rate_other=r_other;    
  rate_all=rate_WEG+rate_phone+rate_school+rate_living+rate_other;   
  income_pay=pay;               
  income_lay=lay;                 
  income_interest=interest;      
  income_other=i_other;     
  income_all=income_pay+income_lay+income_interest+income_other;
  }

 void money::inString()  //输入累的成员变量
  {
    string time;
    cout<<"【时间】(如:2009.6.12):";
 cin>>time;
 date=timedata::read_date(time);
    cout<<"【水电煤气费】:";
    cin>>rate_WEG;
    cout<<"【 电 话 费 】:";
    cin>>rate_phone;
    cout<<"【 学 杂 费 】:";
    cin>>rate_school;
    cout<<"【 生 活 费 】:";
    cin>>rate_living;
    cout<<"【其他项支出】:";
    cin>>rate_other;
    cout<<"【 工    资 】:";
    cin>>income_pay;
    cout<<"【 金融投资 】:";
    cin>>income_lay;
    cout<<"【 存款利息 】:";
    cin>>income_interest;
    cout<<"【 其他收入 】:";
    cin>>income_other;
 rate_all=rate_WEG+rate_phone+rate_school+rate_living+rate_other;
    income_all=income_pay+income_lay+income_interest+income_other;
  }

void money::toString()    //输出类中的成员变量
  {
    string sStars(70,'*'); //产生六十个星号
    cout <<sStars <<endl;
    //让稍后输出输出的时候数据靠左对齐
    cout.setf(ios::left);
    cout<<"【时间】:";
 date.showdate();
 cout<<endl;
    cout<<"【水电煤气费】:";
    cout <<setw(8) <<rate_WEG;
    cout<<"【 电 话 费 】:";
    cout <<setw(8) <<rate_phone;
    cout<<"【 学 杂 费 】:";
    cout <<setw(8) <<rate_school<<endl;
    cout<<"【 生 活 费 】:";
    cout <<setw(8) <<rate_living;
    cout<<"【其他项支出】:";
    cout <<setw(8) <<rate_other;
    cout<<"【 总 支 出 】:";
    cout <<setw(8) <<rate_all<<endl;
    cout<<"【 工    资 】:";
    cout <<setw(8) <<income_pay;
    cout<<"【 金融投资 】:";
    cout <<setw(8) <<income_lay;
    cout<<"【 存款利息 】:";
    cout <<setw(8) <<income_interest<<endl;
    cout<<"【 其他收入 】:";
    cout <<setw(8) <<income_other;
    cout<<"【 总 收 入 】:";
    cout <<setw(6) <<income_all<<endl;
   
  }//end of toString()

Node::Node(money& objArg,Node *nArg=NULL)
  {
    objData=objArg;
    NEXT=nArg;
  }//end of 构造

money MyList::splitStr(string &src, string  &delim)  //如果没有正确的执行,返回的money对象中的data.day值为-1。这个作为调用时候区分的依据。
{
  //因为本例中的money_COLS常量的值是12,所以数据是被11个分隔符隔开,定义11个变量存放分隔符位置
  money objRet;
  objRet.date.day=-1;

  //检测参数
  int iOFF=delim.length();
  if (src.length()==0 || delim.length()==0) return objRet;   //此money对象day为-1,表示错误

  //string类find函数的用法:从第二个参数所指定的索引位置开始,去查找第一个参数在字符串中的位置。如果没有找到,返回string::npos。
  //a,b,c,d,e,f,g,h,i,j,k是11个分隔符的位置
  int a=src.find(delim,0);
  int b=src.find(delim,a+1);
  int c=src.find(delim,b+1);
  int d=src.find(delim,c+1);
  int e=src.find(delim,d+1);
  int f=src.find(delim,e+1);
  int g=src.find(delim,f+1);
  int h=src.find(delim,g+1);
  int i=src.find(delim,h+1);
  int j=src.find(delim,i+1);
  int k=src.find(delim,j+1);
  if (k==string::npos) return objRet;     //如果没有找到第11个分隔符,则返回day等于-1的对象。

  //string类的substr函数,从从指定下标开始截取字符,截取长度由第二个参数指定。如果没有第二个参数,则截取到字符串结尾。
  //根据四个分隔符,截取出五个数据字段
  string d1=src.substr(0,a);
  string r1=src.substr(a+iOFF,b-a-iOFF);
  string r2=src.substr(b+iOFF,c-b-iOFF);
  string r3=src.substr(c+iOFF,d-c-iOFF);
  string r4=src.substr(d+iOFF,e-d-iOFF);
  string r5=src.substr(e+iOFF,f-e-iOFF);
  string r6=src.substr(f+iOFF,g-f-iOFF);
  string i1=src.substr(g+iOFF,h-g-iOFF);
  string i2=src.substr(h+iOFF,i-h-iOFF);
  string i3=src.substr(i+iOFF,j-i-iOFF);
  string i4=src.substr(j+iOFF,k-j-iOFF);
  string i5=src.substr(k+iOFF);

  //将数据存到类的对象中去,string类的字符串要改为C风格的字符串
  objRet.date=timedata::read_date(d1);  
  objRet.rate_WEG=atof(r1.c_str());      
  objRet.rate_phone=atof(r2.c_str());    
  objRet.rate_school=atof(r3.c_str());   
  objRet.rate_living=atof(r4.c_str());   
  objRet.rate_other=atof(r5.c_str());    
  objRet.rate_all=atof(r6.c_str());   
  objRet.income_pay=atof(i1.c_str());               
  objRet.income_lay=atof(i2.c_str());                 
  objRet.income_interest=atof(i3.c_str());      
  objRet.income_other=atof(i4.c_str());     
  objRet.income_all=atof(i5.c_str());
  //将存放了正确数据的对象返回给用户
  return objRet;
}//end of MyList::splitStr(string &src, string  &delim)

MyList::MyList()  //构造函数
{
  START=CURR=PREV=NULL;
}//end of 构造

MyList::~MyList()
{
  destroy();
}

void MyList::destroy()    //对链表中的每个节点,收回内存空间,然后清空链表,析构时调用
{
  while(START!=NULL)
  {
    CURR=START;
    START=START->NEXT;
    delete CURR;
  }//end of while
  START=CURR=PREV=NULL;
}//end of MyList::destroy()

void MyList::addNode(money &obj)  //数据按照时间顺数插入
{
  //添加在开头(链表不存在,或者是要添加到开头)
  if (START==NULL || obj.date <= START->objData.date)
  {
    START=new Node(obj,START);
    return;
  }//end of if
  //添加到链表中间或者末尾
  Node *p,*q;
  p=q=START;
  while(p!=NULL && obj.date > p->objData.date) { q=p,p=p->NEXT;}
  Node *n=new Node(obj,p);
  q->NEXT=n;
}//end of 添加节点

//删除节点,返回bool类型量,false表示为找到
bool MyList::delNode(money &obj)
{
  if(queryNode(obj)==false) return false; 
  PREV->NEXT=CURR->NEXT;
  if (CURR==START)
  START=START->NEXT;
  delete  CURR;       //释放CURR指向的内存
  return true;
}//end of MyList::delNode(money &obj)

//查询节点,返回bool类型(删除节点的时候要调用此函数)
bool MyList::queryNode(money  &obj)  
{
  PREV=CURR=START;
  while(CURR!=NULL && obj.date!=CURR->objData.date) {PREV=CURR,CURR=CURR->NEXT;}
  return  (CURR!=NULL);
}//end of MyList::queryNode(money  &obj)

//遍历所有节点,直接打印所有数据
void MyList::viewAllNodes()
{
  if (size()==0)
  {
    Common::println("链表中没有数据。");
    return;
  }//end of if
  for(Node *temp=START;temp!=NULL;temp=temp->NEXT)
  {
    temp->objData.toString();
  }//end of for
}//end of 遍历节点

//返回节点的数量
int MyList::size()
{
  int n=0;
  Node *temp=START;
  while(temp!=NULL)
  { temp=temp->NEXT;
    n++;
  }
  return n;
}//end of MyList::size()

//从纯文本文件中读取数据,然后存放到链表中。每行数据对应一个对象
void MyList::loadFromTxtFile(const char *fileName,entry obj)
{
  ifstream fIn(fileName,ios::in);
  if (!fIn)
  { char x;
 cout<<endl<<endl<<endl; 
 cout<<"                                     温馨提示       "<<endl<<endl;
 cout<<"      *******************************************************************"<<endl;
 cout<<"          欢迎使用家庭财务管理系统,由于您是第一次是第一次使用本系统,"<<endl;
 cout<<"          系统将在本程序相同路径下为您创建一个文本文件来储存您的财务信"<<endl;
 cout<<"          息,谢谢您的使用!按任意键继续!"<<endl;
 cout<<"      *******************************************************************"<<endl;
 x=getch();
 if(x=='a'||x=='A') cin>>obj.ft_name;
    ofstream f(fileName);
   
  }//end of if


  char chlog[MAXSIZE];
  string sTab="/t"; //数据的分隔符
  while(fIn)
  {
   fIn.getline(chlog,MAXSIZE);        //每次读取一行信息,即1024个字符,读入到chlog字符数组中
   string slog(chlog);     //将读到的当前行的信息,用字符串string的对象来表示
   money objTemp=splitStr(slog,sTab); //把一行的内容,根据分隔符拆分未多个部分,存储到money类的对象中

   //如果返回的对象拥有正确的值,则添加到链表中
   if (objTemp.date.day!=-1) addNode(objTemp);
  }//end of while
  fIn.close();
  Common::println("成功从文本文件中读入数据。");
}//end of MyList::loadFromTxtFile()

//添加数据到纯文本文件
void MyList::saveToTxtFile(const char *fileName)
{
  ofstream fto(fileName,ios::out);
  if(!fto)
  {
    cout <<"无法以写入方式打开" <<fileName <<"文件。/n";
    exit(-1); 
  }
  for(Node *temp=START;temp!=NULL;temp=temp->NEXT)
  {
    fto<<temp->objData.date.year<<'.'<<temp->objData.date.month<<'.'<<temp->objData.date.day<<"/t";
    fto<<temp->objData.rate_WEG<<"/t";
    fto<<temp->objData.rate_phone<<"/t";
    fto<<temp->objData.rate_school<<"/t";
    fto<<temp->objData.rate_living<<"/t";
    fto<<temp->objData.rate_other<<"/t";
    fto<<temp->objData.rate_all<<"/t";
    fto<<temp->objData.income_pay<<"/t";
    fto<<temp->objData.income_lay<<"/t";
    fto<<temp->objData.income_interest<<"/t";
    fto<<temp->objData.income_other<<"/t";
    fto<<temp->objData.income_all<<endl;  
  }//end of for
  fto.close();
  cout<<"成功将链表中的所有信息写入当前目录下的" <<fileName <<"文件。/n";

}

//将链表中的数据,导出到网页文件中
void MyList::exportToHtmlFile(const char *fileName)
{
 string point=".";
  if (size()==0)
  {
    Common::println("链表中没有数据。");
    return;
  }//end of if
  ofstream fOut(fileName,ios::out);
  if (!fOut)
  {
    cout <<"无法以写入方式打开" <<fileName <<"文件。/n";
    exit(-1);
  }//end of if

  //写html文件的开头部分
  fOut<<"<!--本网页由money.exe程序自动生成,作者:殷伟峰 ywf1990@hotmail.com-->"<<endl;
  fOut <<"<html>"<<endl;
  fOut <<"<head><title>程序自动导出的财务信息</title></head>"<<endl;
  fOut <<"<body>"<<endl;
  fOut <<"<center><h2>家庭财务信息浏览</h2><hr></center>"<<endl;
  fOut <<"<div align=center>"<<endl;
  fOut <<"<table border=1 width=100%>"<<endl;

  //表格12列的宽度规划是:12%,8%,8%,8%,8%,8%,8%,8%,8%,8%,8%,8%。各列的宽度不是均分的。
  //写html文件的表格标题行
  fOut <<"<tr>"<<endl;
  fOut <<"<td width=12%><b>时间</b></td>"<<endl;
  fOut <<"<td width=8%><b>水电煤气费</b></td>"<<endl;
  fOut <<"<td width=8%><b>电话费</b></td>"<<endl;
  fOut <<"<td width=8%><b>学杂费</b></td>"<<endl;
  fOut <<"<td width=8%><b>生活费</b></td>"<<endl;
  fOut <<"<td width=8%><b>其它项</b></td>"<<endl;
  fOut <<"<td width=8%><b>总支出</b></td>"<<endl;
  fOut <<"<td width=8%><b>工  资</b></td>"<<endl;
  fOut <<"<td width=8%><b>金融投资</b></td>"<<endl;
  fOut <<"<td width=8%><b>存款利息</b></td>"<<endl;
  fOut <<"<td width=8%><b>其它项</b></td>"<<endl;
  fOut <<"<td width=8%><b>总收入</b></td>"<<endl;
  fOut <<"</tr>"<<endl;

  //通过循环,将所有信息写入网页的表格中
  for(Node *temp=START;temp!=NULL;temp=temp->NEXT)
  {
    //写入表格的正文,通过循环来生成表格正文。
    fOut <<"<tr>" <<endl; //写入表格的第一行
    fOut <<"<td width=12%>" <<temp->objData.date.year<<point<<temp->objData.date.month<<point<<temp->objData.date.day<< "</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.rate_WEG <<"</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.rate_phone <<"</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.rate_school <<"</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.rate_living <<"</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.rate_other <<"</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.rate_all <<"</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.income_pay <<"</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.income_lay <<"</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.income_interest <<"</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.income_other <<"</td>"<<endl;
    fOut <<"<td width=8%>" <<temp->objData.income_all <<"</td>"<<endl;
    fOut <<"</tr>"<<endl;
  }//end of for

  //写入html文件的结尾部分
  fOut <<"</table>"<<endl;
  fOut <<"</div>"<<endl;
  fOut <<"</body></html>";

  fOut.close();
  cout<<"成功将链表中的所有信息导出到当前目录下的" <<fileName <<"文件。/n";
}//end of MyList::exportToHtmlFile()

//对数据做简单统计:求出书籍的平均月收入,平均月支出
void MyList::Avy_all()
{ Common::println(" ",6);
  if (size()==0)
  {
    Common::println("链表中没有数据,平均收入和支出都为0。");
    return;
  }//end of if
  double  rate=0;
  double  income=0;
  double  ratio=0;
  for(Node *temp=START;temp!=NULL;temp=temp->NEXT)
  {
    rate+=temp->objData.rate_all;
    income+=temp->objData.income_all;
  }//end of for
  ratio=(rate+1)/(income+1);
  int iNodes=size();
  cout<<"/t/t/t对"<<iNodes<<"天的统计结果如下:/n";
  cout<<"/t/t/t平均月收入为:" <<((income*30)/iNodes)<<endl;
  cout<<"/t/t/t平均月支出为:"  <<((rate*30)/iNodes) <<endl;
  if(ratio<0)cout<<"/t/t您以进入负资产状态,请注意理财!╯︿╰";
  else if(ratio<3)cout<<"/t/t您的消费偏低,可适当支出,注意理性消费!^_^";
  else if(ratio<6)cout<<"/t/t您一直保持着正常而理性的消费,请继续保持!^_^";
  else if(ratio<8.5)cout<<"/t/t您的消费偏高了,要注意接见哦!╯_╰";
  else if(ratio<10)cout<<"/t/t你的消费过高,请注意理财!╯_╰";
  else cout<<"/t/t/t您以进入负资产状态,请注意理财!╯︿╰";
}//end of MyList::Avy_all()

//按时间寻找,查看功能使用的函数,找到后直接打印
void MyList::findBydate(timedata d1,timedata d2)
{
  //日期是惟一的,如果找到后,就可以立即返回
  for(Node *temp=START;temp!=NULL;temp=temp->NEXT)
  {
    if (temp->objData.date>=d1&&temp->objData.date<=d2)
    {
      temp->objData.toString();   //objData是money的一个对象,调用toString输出数据
   if(temp->objData.date==d2)    return;   //结束函数
    }//end of if

  }//end of for

  d1.showdate();   
  cout<<"的数据不存在。/n";        //如果没有在for循环中找到数据,并用return返回,则表示没有找到
}//end of MyList::findBydate(timedata date)


//main.cpp
#include "iostream"      //输入输出用到"iostream"
#include "fstream"      //文件操作用到"fstream"
#include "iomanip"      //setw和setfill格式化输出用到"iomanip"
#include "string"      //字符串用到"string"
#include "conio.h"      //getch需用到"conio.h"
#include "money.h"
#include "money.cpp"
using namespace std;

//此函数在各个类之外,和main平行,被main函数调用。
void waitForMe()
{
Common::pause();//调用Common类的静态函数pause,让程序暂停,用户按键后再继续。
Common::clear();
}

void main()
{
  char a,b,c,d,e,f;     //用于记录选择的菜单项
  Common objCommon;    //定义Conmom的对象,用来调用常用的函数
  entry objen;     //定义entry对象……
  AccountList objAcLst;    //定义AccountList的对象
  MyList objLst;
  objCommon.backcolor();  //设置主题,背景、前景颜色 
  objAcLst.loadpassword(KEY_FILE);  //读取用户信息
  a=objCommon.login();   //显示注册、登陆界面,取得返回值(char)1.登陆、2.注册、3.退出
  entry T_obj;
  Node_entry *FNP;
  switch(a)
  {
  case '1':FNP=objAcLst.vali_key();
         T_obj.ID=FNP->objentry.ID;
         T_obj.key=FNP->objentry.key;  
   break;
  case '2':c=T_obj.setkey();  //注册,并返回值Y.登陆、N.退出
     objAcLst.addNode_entry(T_obj);
     objAcLst.savepassword(KEY_FILE);
        if(c=='y'||c=='Y')
     {objAcLst.vali_key();break;}
        else exit(0);
  case '3':exit(0);
  }
 
 
  objCommon.showMySplash();  //显示版权窗口
  waitForMe();     //暂停……

  cout<<"                        1.正在从文件中加载数据到链表";
  objCommon.WordByWord("......");
  objLst.loadFromTxtFile(T_obj.filename().c_str(),T_obj);
  waitForMe();
for(;;)
{
  b=objCommon.showMyMenu();  //显示菜单,返回选项,(char)1.1.添加、2.查看、3.删除、4.综合管理、5.保存6.退出 
  timedata d1(0,0,0);
  timedata d2(0,0,0);
  string stime2;  //临时储存数据,供查找是用
  money T_mon;   //临时储存数据,供查找是用
  switch(b)
  {
  case '1': for(;;)
   {money objmoney;
    objmoney.inString();
    objLst.addNode(objmoney);
    objCommon.println("      ---------------------数据加载成功,继续? Y/N---------------------");
    c=getch();
    if(c=='Y'||c=='y') continue;
    else break;
             Common::clear();
   }break;
             
  case '2': objCommon.println("             ",7);
            objCommon.println("                                1.自定义查找",2);
            objCommon.println("                                2.查看所有记录");
   d=getch();
   Common::clear();
   if(d=='1')  
   { string stime1;
     string stime2;
     objCommon.println("             ",7);
     cout<<"              输入要查询时间段的起始时间(如:2009.6.12):";
     cin>>stime1;
     cout<<"                            输入终止时间(如:2009.6.12):";
     cin>>stime2;
              d1=timedata::read_date(stime1);
              d2=timedata::read_date(stime2);
              Common::clear();
     cout<<"                从"<<stime1<<"到"<<stime2<<"的信息显示如下";
        objCommon.WordByWord("......");
        objLst.findBydate(d1,d2);
              waitForMe();   
   }
   if(d=='2')
   {
     cout<<"                        显示链表中的所有数据";
     objCommon.WordByWord("......");
     objLst.viewAllNodes();
     waitForMe();   
   }
            break;
  case '3':for(;;)
   {
   objCommon.println("             ",6);
   cout<<"                    输入信息储存时间(如:2009.6.12):";
   cin>>stime2;
            T_mon.date=timedata::read_date(stime2);
            if(objLst.delNode(T_mon))
   {cout<<endl<<"                     日期"<<stime2<<"储存的信息已删除";break;}
   else
   {cout<<endl<<endl<<"                       没有找到您要删除的文件,重新输入?"<<endl;
   cout<<"                          Y:重新输入     N:返回上一层"<<endl;}
   f=getch();
    if(f=='N'||f=='n') break;
   }//end for
   break;
  case '4': for(;;)
   {
   string stime3;
   objCommon.println("             ",6);
   cout<<"                    输入信息储存时间(如:2009.6.12):";
   cin>>stime3;
            T_mon.date=timedata::read_date(stime3);
            if(objLst.delNode(T_mon))
   {money objmoney;
    objmoney.inString();
    objLst.addNode(objmoney);break;}
   else
   {cout<<endl<<endl<<"                       没有找到您要修改的文件,重新输入?"<<endl;
   cout<<"                          Y:重新输入     N:返回上一层"<<endl;}
   e=getch();
    if(e=='N'||e=='n') break;
   }//end for
   break;
  case '5': objLst.Avy_all();waitForMe();break;
  case '6': objLst.saveToTxtFile(T_obj.filename().c_str());
   objLst.exportToHtmlFile(T_obj.htmlname().c_str());
            waitForMe();
   break;
  case '7': exit(0);
}  
  }
}//end  of main

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值