调查统计员(源码2)

// ****************************************************************************/
//  Functions.cpp   version:  1.0     date: 12/12/2005                         /
//  ---------------------------------------------------------------------------/
//  Summary:                                                                   /
//  ---------------------------------------------------------------------------/
//  Copyright (C) LYH_Studio @ 2005 - All Rights Reserved                      /
// ****************************************************************************/
//                                                                             /
// ****************************************************************************/
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <utility>
using namespace std;


#include "MainInclude.h"
#include "Functions.h"


//--------------------------------------------------------------------------------------->>
//定义枚举和字符串常量。其用于保存错误信息。*
//------------------------------------------*
#ifndef _LYH_STUDIO_COMMANDS
#define _LYH_STUDIO_COMMANDS

map<string,ComFunc*> funcMap;

#endif

#ifndef _LYH_STUDIO_ERR_MSG_CHAR
#define _LYH_STUDIO_ERR_MSG_CHAR

#ifndef _LYH_STUDIO_ERR_MSG_ENUM
#define _LYH_STUDIO_ERR_MSG_ENUM
enum PARAMETER_ERROR{ERR_MSG_ILLEGAL_STATEMENT, ERR_MSG_WANTING_PARAMETER,
ERR_MSG_TOO_MANY_PARAMETERS, ERR_MSG_PARAMETER_ERROR, ERR_MSG_WANTING_NUMBER,
ERR_MSG_OUTOF_RANGE, ERR_MSG_OPEN_FILE_FAIL, ERR_MSG_FILE_UNCONSISTENT, ERR_MSG_UNKNOWN_ERROR};
#endif

char *errMsg[9] = {"非法语句!", "命令缺少参数!", "命令包含太多参数!",
"命令参数输入错误。选项未定义!", "需要输入数字", "超过可输入范围",
"打开文件失败!文件不存在或者已经损坏。", "统计选项不一致!"
"出现未知错误!请与计算机科学与技术 1 班 李业华 联系。"};

#endif
//--------------------------------------------------------------------------------------->>


/*-------------Function @ StatisticComDispatch @ discription <----------------*
*@name: void StatisticComDispatch();                                          *
*@parameter:                                                                  *
*@purpose: It is used for despatching commands                                *
*@return value: void                                                          *
*-----------------------------------------------------------------------------*/
void StatisticComDispatch() {
 //功能函数入表
 funcMap.insert(make_pair(string("AmountShow"), &AmountShow));
 funcMap.insert(make_pair(string("RelativeShow"), &RelativeShow));
 funcMap.insert(make_pair(string("new"), &NewStatistic));
 funcMap.insert(make_pair(string("continue"), &Continue));
 funcMap.insert(make_pair(string("reInput"), &ReInput));
 funcMap.insert(make_pair(string("import"), &ReadFromFile));
 funcMap.insert(make_pair(string("export"), &WriteToFile));
 funcMap.insert(make_pair(string("makeFile"), &WrFmToFile));
 funcMap.insert(make_pair(string("showData"), &ShowData));
 funcMap.insert(make_pair(string("help"), &ShowHelp));
 funcMap.insert(make_pair(string("quit"), &Quit));
 
 //----------------------------------------------------//
 
 stringEx strCI, strData;
 
 cout << "请输入你的命令:(输入help获得帮助) " << endl;
 
 char command[COMMAND_MAX_LENGTH];
 stringEx strCommand;
 stringEx subCommand;
 
 
 //===================================================//
 //              以下是处理命令的代码                 //
 //===================================================// 
 
 do {
  cin >> strCommand;
  cin.getline(command, COMMAND_MAX_LENGTH);
  
  if (!cin) {  //命令输入错误
   clog << "命令输入错误!  请重新输入。" << endl;
   continue ;
  }
  //**********************************************//
  //-----> 如果输入正常则执行下面语句 <-----------//
  //**********************************************//
  
  //把命令行保存到字符串对象中
  strCommand.append(command,0,COMMAND_MAX_LENGTH);
  
  
  
  //保存选项
  int selection = 0;
  
  try {
   //如果整个命令行不是少于三步分(用两个空格分开)的话,就提示命令输入错误
   if (strCommand.GetSubStringNum(DATA_DIVIDER) > 3) {
    throw errMsg[ERR_MSG_TOO_MANY_PARAMETERS];
   }
   //逐个判断命令
   subCommand = strCommand.GetSubString(1, DATA_DIVIDER);
   
   if (funcMap.find(subCommand) != funcMap.end()) {
    ShowDivideLine(true);
    
    (*funcMap[subCommand])(strCI, strData, strCommand);
    
    ShowDivideLine(false);
   }
   else {
    throw errMsg[ERR_MSG_ILLEGAL_STATEMENT];
   }
  }
  catch (stringEx::InvtStringException err) {
   clog << err.GetErrMsg() << endl;
   
   ShowDivideLine(false);
   
   continue;
  }
  catch (const char *errMsg) {
   clog << errMsg << endl;
   
   ShowDivideLine(false);
   
   continue;
  }
  catch (...) {
   clog << errMsg[ERR_MSG_UNKNOWN_ERROR] << endl;
   getch();
   
   abort();
  }
 }while(true);
}


/*------------------>Function @ AmountShow @ discription <--------------------*
*@name:void AmountShow(stringEx &strCI,                                       *
stringEx &strData, stringEx &strCommand);                                     *
*@parameter:stringEx &strCI, stringEx &strData                                *
*@purpose:show the result of statistic in characters                          *
*@return value:void                                                           *
*-----------------------------------------------------------------------------*/
void AmountShow(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 Investigator_Amount invtorAmount(strData, strCI);
    
 //获得选项的位
 int selection = Investigator_Amount::Command::GetParameter(strCommand.GetSubString(2, DATA_DIVIDER));
    
    
 if (strCommand.GetSubString(3, DATA_DIVIDER) == "--all") {
  if ((selection & Investigator_Amount::Command::PICTURE) != 0) {
   invtorAmount.InvtAndDrawMastAll();
  }
  
  if ((selection & Investigator_Amount::Command::NOTICE) != 0) {
   invtorAmount.InvtAndNoticeAll();
  }
 } 
 else {
  if ((selection & Investigator_Amount::Command::PICTURE) != 0) {
   invtorAmount.InvtAndDrawMast(strCommand.GetSubString(3, DATA_DIVIDER));
  }
  
  if ((selection & Investigator_Amount::Command::NOTICE) != 0) {
   invtorAmount.InvtAndNotice(strCommand.GetSubString(3, DATA_DIVIDER));
  }
 }
}


/*----------------->Function @ RelativeShow @ discription <-------------------*
*@name: void RelativeShow(stringEx &strCI,                                    *
stringEx &strData, stringEx &strCommand);                                     *
*@parameter:stringEx &strCI, stringEx &strData                                *
*@purpose: show the result of statistic in mast picture                       *
*@return value: void                                                          *
*-----------------------------------------------------------------------------*/
void RelativeShow(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 Investigator_Relative invtorRelative(strData, strCI);
    
    //获得选项的位
    int selection = Investigator_Relative::Command::GetParameter(strCommand.GetSubString(2, DATA_DIVIDER));
    
    
 if ((selection & Investigator_Relative::Command::PICTURE) != 0) {
  invtorRelative.InvtAndDrawMast(strCommand.GetSubString(3, DATA_DIVIDER));
 }
    
    
 if ((selection & Investigator_Relative::Command::NOTICE) != 0) {
  invtorRelative.InvtAndNotice(strCommand.GetSubString(3, DATA_DIVIDER));
 }
}


/*----------------->Function @ NewStatistic @ discription <-------------------*
*@name: void NewStatistic(string &strCI,                                      *
string &strData, stringEx &strCommand);                                       *
*@parameter: void                                                             *
*@purpose: main callback function for "Ton Ji"                                *
*@return value:void                                                           *
*-----------------------------------------------------------------------------*/
void NewStatistic(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 if (strCommand.GetSubStringNum(DATA_DIVIDER) != 1) {
  AnnounceError(errMsg[ERR_MSG_TOO_MANY_PARAMETERS]);
  return;
 }
 else if (strCI.length() != 0) {
  int ch;
l3:  cout << "是否放弃当前项目?(y/n)" << endl;
  if ((ch = getch()) == 'n' || ch == 'N'){
   cout << "没有新建任何项目。" << endl;
   return;
  }
  else if (ch == 'y' || ch == 'Y') {
   strCI = "";
   strData = "";
  }
  else {
   AnnounceError("输入错误!");
   goto l3;
  }
 }
 
 cout << "输入选项子串:" << endl;
 cin  >> strCI;
 
 while (!IsDifferent(strCI)) {
  AnnounceError("你输入了名字相同的选项!");
  
  cout << "输入选项子串:" << endl;
  cin  >> strCI;
 }
 
 cout << "参与调查共有" << InputData(strData, strCI) << "人" << endl;
 
}


/*-------------------->Function @ continue @ discription <--------------------*
*@name: void Continue(stringEx &strCI,                                        *
stringEx &strData, stringEx &strCommand);                                     *
*@parameter: stringEx &strCI, stringEx &strData, stringEx &strCommand         *
*@purpose:continue the statistic                                              *
*@return value:void                                                           *
*-----------------------------------------------------------------------------*/
void Continue(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 if (strCommand.GetSubStringNum(DATA_DIVIDER) != 1) {
  AnnounceError(errMsg[ERR_MSG_TOO_MANY_PARAMETERS]);
  return;
 }
 else if (strCI.length() == 0) {
  AnnounceError("缺少项目!", "请先创建项目");
  return;
 }
 
 cout << "参与调查共有" << InputData(strData, strCI) << "人" << endl;
 
}


/*------------------>Function @ ReInput @ discription <-----------------------*
*@name: void ReadFromFile(stringEx &strCI,                                    *
stringEx &strData, stringEx &strCommand);                                     *
*@parameter: void                                                             *
*@purpose: reinput data                                                       *
*@return value: void                                                          *
*-----------------------------------------------------------------------------*/
void ReInput(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 short parameterNum = strCommand.GetSubStringNum(DATA_DIVIDER);
 if (parameterNum < 3) {
  AnnounceError(errMsg[ERR_MSG_WANTING_PARAMETER]);
  return;
 }
 else if (parameterNum > 3) {
  AnnounceError(errMsg[ERR_MSG_TOO_MANY_PARAMETERS]);
  return;
 }
 else if (strCI.length() == 0 || strData.length() == 0) {
  AnnounceError("缺少项目!", "请先创建项目");
  return;
 }
 
 
 stringEx rstr(strCommand.GetSubString(3, DATA_DIVIDER));
 if (!IsDifferent(rstr)) {
  AnnounceError("你输入了相同的选项!", "请再输入一次!");
 }
 else if (!IsInSelection(rstr, strCI)) {
  AnnounceError("你输入了错误的选项!", "请再输入一次!");
 }
 else {
  unsigned int index = 1;  // base on 1
  if ((index = strCommand.ConvertSubStrToUINT(2, DATA_DIVIDER)) >= 1 && index <= strData.GetSubStringNum(DATA_DIVIDER)) {
   strData.replace(index, rstr, DATA_DIVIDER);

   cout << "您的修改已成功。" << endl;
  }
  else {
   throw errMsg[ERR_MSG_OUTOF_RANGE];
  }
 }
}


/*---------------->Function @ ReadFromFile @ discription <--------------------*
*@name: void ReadFromFile(stringEx &strCI,                                    *
stringEx &strData, stringEx &strCommand);                                     *
*@parameter: void                                                             *
*@purpose: read old data from file                                            *
*@return value: void                                                          *
*-----------------------------------------------------------------------------*/
void ReadFromFile(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 if (strCommand.GetSubStringNum(DATA_DIVIDER) <= 1) {
  AnnounceError(errMsg[ERR_MSG_WANTING_PARAMETER]);
  return;
 }
 
 if (strCI.length() != 0) {
  int ch;
l2:  cout << "是否放弃当前项目?(y/n)" << endl;
  if ((ch = getch()) == 'n' || ch == 'N'){
   cout << "没有加载任何文件。" << endl;
   return;
  }
  else if (ch == 'y' || ch == 'Y') {
   strCI = "";
   strData = "";
  }
  else {
   AnnounceError("输入错误!");
   goto l2;
  }
 }
 
 stringEx fName = strCommand.GetSubString(2, DATA_DIVIDER);
 ifstream file;
 
 //判断如果是否参数选项-m
 if (fName == "-m") {
  stringEx strFile = strCommand.GetSubString(3, DATA_DIVIDER);
  unsigned int iFileNum = strFile.GetSubStringNum(PARAMETER_DIVIDER);
  strSet fileNames;
  strSet errFileNames;
  
  if (iFileNum <= 0) {
   AnnounceError(errMsg[ERR_MSG_WANTING_PARAMETER]);
   return;
  }
  else {
   //把文件名载入set
   pair<strSet::iterator,bool> result;
   for (int i = 1; i <= iFileNum; i++) {
    result = fileNames.insert(strFile.GetSubString(i, PARAMETER_DIVIDER) + ".LYH_Sta");
    if (!result.second) {
     AnnounceError(string("文件列表中有相同的文件名:") + *result.first,
      "该文件将不被加载。");
    }
   }
   
   
   for (strSet::iterator pos = fileNames.begin(); pos != fileNames.end(); ++pos) {
    file.open((*pos).c_str(), ios::in);
    
    if (file) {
     stringEx tempstr;
     
     getline(file, tempstr);
     if (strCI.length() != 0) {
      if (tempstr != strCI) {
       AnnounceError(string(errMsg[ERR_MSG_FILE_UNCONSISTENT]),
        string("数据文件<") + fName + "导入失败!");
       
       strCI = "";
       strData = "";
       
       file.close();
       return;
      }
      else {
       getline(file, tempstr);
       strData += ' ';
       strData += tempstr;
      }
     }
     else {
      strCI = tempstr;
      getline(file, tempstr);
      strData = tempstr;
     }
     
     file.close();
    }
    else {
     file.clear();
     
     errFileNames.insert(*pos);
    }
   }
   
   if (!errFileNames.empty()) {
    string errFile;
    for (strSet::iterator pos = errFileNames.begin(); pos != errFileNames.end(); ++pos) {
     errFile += *pos + "  ";
    }
    
    AnnounceError(string("文件:") + errFile + string("导入失败!"), errMsg[ERR_MSG_OPEN_FILE_FAIL]);
   }
   else {
    cout << "导入成功!" << endl;
   }
  }
 }
 else if (fName == "end") {
  return;
 }
 else {
  if (strCommand.GetSubStringNum(DATA_DIVIDER) > 2) {
   AnnounceError(errMsg[ERR_MSG_TOO_MANY_PARAMETERS]);
   return;
  }
  else {
   fName += ".LYH_Sta";
   file.open(fName.c_str(), ios::in);
   
   if (!file) {
    AnnounceError(errMsg[ERR_MSG_OPEN_FILE_FAIL]);
    
    file.clear();
    
    return;
   }
   else {
    getline(file, strCI);
    getline(file, strData);
    
    file.close();
    
    cout << "导入数据成功!" << endl;
    return;
   }
  }
 }
 
 
}


/*------------------>Function @ WriteToFile @ discription <-------------------*
*@name: void WriteTpFile(stringEx &strCI,                                     *
stringEx &strData, stringEx &strCommand);                                     *
*@parameter: stringEx strCI, stringEx strData                                 *
*@purpose:write data to file                                                  *
*@return value: void                                                          *
*-----------------------------------------------------------------------------*/
void WriteToFile(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 short parameterNum = strCommand.GetSubStringNum(DATA_DIVIDER);
 if (parameterNum < 2) {
  AnnounceError(errMsg[ERR_MSG_WANTING_PARAMETER]);
  return;
 }
 else if (parameterNum > 2) {
  AnnounceError(errMsg[ERR_MSG_TOO_MANY_PARAMETERS]);
  return;
 }
 else if (strCI.length() == 0 || strData.length() == 0) {
  AnnounceError("项目没定义或缺少统计数据!", "请输入统计数据后再导出数据文件。");
  return;
 }//保证数据存在
 
 stringEx fName = strCommand.GetSubString(2, DATA_DIVIDER);
 ofstream file;
 
 do {
  if (fName == "end") {
   return;
  }
  else {
   //处理文件名
   fName += ".LYH_Sta";
   
   file.open(fName.c_str(), ios::out|ios::trunc);
   
   if (!file) {
    AnnounceError(errMsg[ERR_MSG_OPEN_FILE_FAIL]);
    file.clear();
    
    cout << "请输入要导出的数据文件(STA_LYH)名字。" << endl;
    cin >> fName;
    
    continue;
   }
   else {
    break;
   }
  }
 }while (true);
 
 file.write(strCI.c_str(), strCI.length());
 file.put('/n');
 file.write(strData.c_str(), strData.length());
 file.put('/n');
 
 file.close();
 
 cout << "写入文件成功!" << endl;
}


/*------------------>Function @ WrFmToFile @ discription <--------------------*
*@name: void WrFmToFile(stringEx &strCI,                                      *
stringEx &strData, stringEx &strCommand);                                     *
*@parameter: stringEx &strCI, stringEx &strData, stringEx &strCommand         *
*@purpose:write data to file                                                  *
*@return value: void                                                          *
*-----------------------------------------------------------------------------*/
void WrFmToFile(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 short parameterNum = strCommand.GetSubStringNum(DATA_DIVIDER);
 if (parameterNum < 2) {
  AnnounceError(errMsg[ERR_MSG_WANTING_PARAMETER]);
  return;
 }
 else if (parameterNum > 2) {
  AnnounceError(errMsg[ERR_MSG_TOO_MANY_PARAMETERS]);
  return;
 }
 else if (strCI.length() == 0 || strData.length() == 0) {
  AnnounceError("项目没定义或缺少统计数据!", "请输入统计数据后再导出数据文件。");
  return;
 }//保证数据存在
 
 stringEx fName = strCommand.GetSubString(2, DATA_DIVIDER);
 ofstream file;
 
 do {
  if (fName == "end") {
   return;
  }
  else {
   //文件后缀
   fName += ".txt";
   
   file.open(fName.c_str(), ios::out|ios::trunc);
   
   if (!file) {
    AnnounceError(errMsg[ERR_MSG_OPEN_FILE_FAIL]);
    file.clear();
    
    cout << "请输入要导出的数据文件(STA_LYH)名字。" << endl;
    cin >> fName;
    
    continue;
   }
   else {
    break;
   }
  }
 }while (true);
 
 stringEx temp;
 unsigned int ID = 1;
 stringEx::const_iterator pos = strData.begin();
 
 //首先写入标题
 temp += "***************";
 temp += fName;
 temp += "***************/n";
 
 temp += stringEx("选项:") + strCI + "/n----------------------------------->/n/n";
 
 temp += stringEx("第") + (ID++) + "号调查者:";
 while (pos != strData.end()) {
  if (*pos != DATA_DIVIDER) {
   temp += *pos;
  }
  else {
   temp += stringEx("/n第") + (ID++) + "号调查者:";
  }
  
  ++pos;
 }
 temp += string("/n") + "************************************/n";
 
 file.write(temp.c_str(), temp.length());
 
 
 //把输出重定向文件,以输出调查结果
 streambuf *oldbuf = cout.rdbuf(file.rdbuf());
 
 Investigator_Amount  amount(strData, strCI);
 amount.InvtAndNoticeAll();
 
 cout.rdbuf(oldbuf);
 
 
 file.close();
 
 cout << "输出文件成功!" << endl;
}


/*------------------>Function @ ShowData @ discription <----------------------*
*@name: void ShowData(stringEx &strCI,                                        *
stringEx &strData, stringEx &strCommand);                                     *
*@parameter: stringEx &strCI, stringEx &strData, stringEx &strCommand         *                                                        *
*@purpose: show data to scane                                                 *
*@return value: void                                                          *
*-----------------------------------------------------------------------------*/
void ShowData(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 if (strCommand.GetSubStringNum(DATA_DIVIDER) > 1) {
  AnnounceError(errMsg[ERR_MSG_TOO_MANY_PARAMETERS]);
  return;
 }
 else if (strCI.length() == 0 || strData.length() == 0) {
  AnnounceError("项目没定义或缺少统计数据!", "请输入统计数据后再导出数据文件。");
  return;
 }//保证数据存在

 stringEx temp;
 unsigned int ID = 1;
 stringEx::const_iterator pos = strData.begin();

 
 temp = stringEx("选项:") + strCI + "/n------------------------------>/n/n";
 
 temp += stringEx("第") + (ID++) + "号调查者:";
 while (pos != strData.end()) {
  if (*pos != DATA_DIVIDER) {
   temp += *pos;
  }
  else {
   temp += stringEx("/n第") + (ID++) + "号调查者:";
  }
  
  ++pos;
 }
 
 cout << temp << endl;
}

/*-------------------->Function @ InputData @ discription <-------------------*
*@name: int InputData(string &strData, stringEx &strCI);                      *
*@parameter: const stringEx &strCI, stringEx &strData                         *
*@purpose: show cue and ask client to input data                              *
*@return value: int  =====>>return amount of data                             *
*-----------------------------------------------------------------------------*/
int InputData(stringEx &strData, stringEx &strCI) {
 string strTemp;
 int ID = strData.GetSubStringNum(DATA_DIVIDER);
 ID = ID == 1 ? 1 : ID + 1;    //修改ID的值适应新建与继续两个命令的需要
 
 int oldIndex = 0;             //记录最近一次的数据在strData中的下标
 
 
 cout << "请输入参与者的选择:" << endl;
 cout << "第" << ID << "个:";
 cin >> strTemp; 
 while (strTemp != "end") {
  //通过验证后,把上次输入的数据追加到strData后面
  if (ID > 1 && strTemp[0] == '~') {
   
   
   if (!IsDifferent(strTemp)) {
    AnnounceError("你输入了相同的选项!", "请再输入一次!");
    
    ID--;
   }
   else if (!IsInSelection(strTemp.substr(1), strCI)) {
    AnnounceError("你输入了错误的选项!", "请再输入一次!");
    
    ID--;
   }
   else {
    strData.erase(oldIndex);
    strData += strTemp.substr(1) + DATA_DIVIDER;
    ID--; 
   }
  }
  else {
   if (!IsDifferent(strTemp)) {
    AnnounceError("你输入了相同的选项!", "请再输入一次!");
    
    ID--;
   }
   else if (!IsInSelection(strTemp, strCI)) {
    AnnounceError("你输入了错误的选项!", "请再输入一次!");
    
    ID--;
   }
   else {
    oldIndex = strData.length();
    strData += strTemp + DATA_DIVIDER; 
   }
  }
  
  cout << "第" << ++ID << "个:";
  cin >> strTemp;
 }
 
 //去除尾部的DATA_DIVIDER
 if (strData[strData.length()-1] == DATA_DIVIDER) {
  strData.erase(strData.length()-1, 1);
 }
 
 ShowDivideLine(true);
 
 return ID - 1;
}


/*------------------>Function @ IsDifferent @ discription <-------------------*
*@name: bool IsDifferent(const string &str);                                  *
*@parameter: const string &str                                                *
*@purpose: decide whether the characters in the str is different              *
*@return value: bool                                                          *
*-----------------------------------------------------------------------------*/
bool IsDifferent(const stringEx &str) {
 const char *strData = str.data();
 int length = str.length();
 
 for (int i = 0; i < length - 1; i++) {
  for (int j = i + 1; j < length; j++) {
   if (strData[i] == strData[j])
    return false;
  }
 }
 
 return true;
}


/*---------------->Function @ IsInSelection @ discription <-------------------*
*@name: bool IsInSelection(const stringEx &str, const string &strCI);         *
*@parameter: const string &str                                                *
*@purpose: decide whether the characters in the str is in the selections      *
*@return value:                                                               *
*-----------------------------------------------------------------------------*/
bool IsInSelection(const stringEx &str, const stringEx &strCI) {
 if (!str.length()) {
  return false;
 }
 else {
  return str.IsSubCharSet(strCI);
 }
}


/*----------------->Function @ AnnounceError @ discription <------------------*
*@name:void AnnounceError(const char *const err, const char *const errEx);    *
*@parameter:const char *const err, const char *const errEx                    *
*@purpose:show error message to screen                                        *
*@return value:void                                                           *
*-----------------------------------------------------------------------------*/
void AnnounceError(const char *const err, const char *const errEx) {
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
  FOREGROUND_RED|FOREGROUND_INTENSITY);
 if (errEx != NULL) {
  //这里的clog是标准错误流,作用和cout差不多,
  //只不过clog多用于输出标准的错误信息,而cout则多用于输出普通信息
  clog << endl
   << err << endl
   << errEx << endl
   << "^__^      /n" << endl;
 }
 else {
  clog << endl
   << err << endl
   << "^__^      /n" << endl;
 }
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
  FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);
}


/*----------------->Function @ AnnounceError @ discription <------------------*
*@name:void AnnounceError(const string err, const string errEx);              *
*@parameter:const char *const err, const char *const errEx                    *
*@purpose:show error message to screen                                        *
*@return value:void                                                           *
*-----------------------------------------------------------------------------*/
void AnnounceError(const string err, const string errEx) {
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
  FOREGROUND_RED|FOREGROUND_INTENSITY);
 if (errEx != "") {
  //这里的clog是标准错误流,作用和cout差不多,
  //只不过clog多用于输出标准的错误信息,而cout则多用于输出普通信息
  clog << endl
   << err << endl
   << errEx << endl
   << "^__^      /n" << endl;
 }
 else {
  clog << endl
   << err << endl
   << "^__^      /n" << endl;
 }
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
  FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);
}


/*--------------------->Function @  @ discription <---------------------------*
**@name:bool Compare(char a, char b);                                         *
*@parameter:# char a                                                          *
# char b    ======>>compare unit                                              *
*@purpose:compare char a and char b                                           *
*@return value:bool                                                           *
*-----------------------------------------------------------------------------*/
bool Compare(char a, char b) {
 return a > b;
};


/*------------------>Function @ ShowHelp @ discription <----------------------*
**@name: void ShowHelp(stringEx &strCI,                                       *
stringEx &strData, stringEx &strCommand);                                     *
*@parameter:void                                                              *
*@purpose:show help documents to client                                       *
*@return value:void                                                           *
*-----------------------------------------------------------------------------*/
void ShowHelp(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 if (strCommand.GetSubStringNum(DATA_DIVIDER) > 1) {
  AnnounceError(errMsg[ERR_MSG_TOO_MANY_PARAMETERS]);
  return;
 }

 //设置显示字体为高亮
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
  FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
 
 
 cout << endl;
 
 ShowColorText("注意! 本程序命令区分大小写!", FOREGROUND_GREEN|FOREGROUND_INTENSITY);
 
 cout << "命令:" ; ShowColorText("new", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "参数:" << "(空)"<< endl;
 cout << "用途:" << "创建一个新的项目。" << endl;
 cout << "例子:new↓ 表示新创建一个项目,以前的项目(如果有)数据将会被覆盖。" << endl;
 
 cout << endl;
 
 cout << "命令:" ; ShowColorText("continue", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "参数:" << "(空)" << endl;
 cout << "用途:" << "继续当前统计项目的输入。" << endl;
 cout << "例子:continue↓ 表示继续当前的统计数据输入。" << endl;
 
 cout << endl;
 
 cout << "命令:" ; ShowColorText("~", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "参数:" << "紧跟着修改后的数据" << endl;
 cout << "用途:" << "用于在数据输入过程中修改上一位调查者的数据。" << endl;
 cout << "例子:~liyehua↓表示把上一个调查者的选择改为liyehua。" << endl;
 
 cout << endl;
 
 cout << "命令:" ; ShowColorText("reInput", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "参数:" << "第一个:调查者代号。 第二个:新的数据" << endl;
 cout << "用途:" << "修改相应调查者的选择" << endl;
 cout << "例子:reInput 2 liyehua↓表示修改第二个调查者的选择,使它变为liyehua。" << endl;
 
 cout << endl;

 cout << "命令:" ; ShowColorText("showData", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "参数:" << "(空)"<< endl;
 cout << "用途:" << "显示当前项目的信息。" << endl;
 cout << "例子:showData↓ 表示显示当前项目的信息。" << endl;
 
 cout << endl;
 
 cout << "命令:" ; ShowColorText("import", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "参数:" << "1、已存在的数据文件名或文件地址。若数据文件在本程序的相对目录下,则可以只输入文件名;否则必须输入完整的地址。"
  << "数据文件后缀(.LYH_STA)会由程序自动加上去。"
  << "2、选项“-m”:可以导入多个文件(与输入顺序无关)。加上这选项后,第三个参数是用“-”连接的文件名串。"
  << "数据文件后缀(.LYH_STA)会由程序自动加上去。" << endl;
 cout << "用途:" << "导入已经存在的数据文件。" << endl;
 cout << "例子1:import liyehua↓表示载入文件名为liyehua.LYH_STA的数据文件。" << endl;
 cout << "例子2:import -m li-ye-hua↓表示载入li.LYH_STA、ye.LYH_STA、hua.LYH_STA三个数据文件。" << endl;
 
 cout << endl;
 
 cout << "命令:" ; ShowColorText("export", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "参数:" << "已存在的数据文件名或文件地址。若数据文件在本程序的相对目录下,则可以只输入文件名;否则必须输入完整的地址。"
  << "数据文件后缀是:.LYH_STA" << endl;
 cout << "用途:" << "导出当前项目的数据文件。" << endl;
 cout << "例子:export liyehua↓表示导出文件名为liyehua.LYH_STA的数据文件。" << endl;
 
 cout << endl;
 
 cout << "命令:" ; ShowColorText("makeFile", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "参数:" << "已存在的数据文件名或文件地址。若数据文件在本程序的相对目录下,则可以只输入文件名;否则必须输入完整的地址。"
  << "数据文件后缀(.txt)会由程序自动加上去。" << endl;
 cout << "用途:" << "制作当前项目的文本文件,以供浏览。" << endl;
 cout << "例子:makeFile liyehua↓表示制作文件名为liyehua.txt的文本文件。" << endl;
 
 cout << endl;
 
 cout << "命令:" ; ShowColorText("AmountShow", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "参数:" << "-p:以柱状图显示。"
  << "-n:以文字显示。" << endl;
 cout << "保留关键字:" << "--all:显示所有选项的统计结果。" << endl;
 cout << "用途:" << "显示“数量”统计的结果" << endl;
 cout << "例子:/nAmountShow -p-n liyehua/n表示用柱状图和文字显示选项l i y e h u a各自的统计结果" << endl;
 cout << "例子:/nAmountShow -n --all/n表示用文字显示所有选项的统计结果" << endl;
 
 cout << endl;
 
 cout << "命令:" ; ShowColorText("RelativeShow", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "参数:" << "-p:以柱状图显示。"
  << "-n:以文字显示。"
  //<< "-all:显示所有可能的组合的统计结果。"
  << endl;
 cout << "用途:" << "显示“关联”统计的结果" << endl;
 cout << "例子:/nRelativeShow -p-n LYH/n表示用柱状图和文字显示选项L Y H三个选项的关联次数" << endl;
 
 cout << endl;
 
 cout << "命令:" ; ShowColorText("quit", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "用途:" << "推出本程序" << endl;
 
 cout << endl;
 
 cout << "命令:" ; ShowColorText("help", FOREGROUND_RED|FOREGROUND_INTENSITY);
 cout << "用途:" << "显示帮助" << endl;
 
 cout << endl;
 
 
 //回复字体显示属性
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
  FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
}


/*-------------------->Function @ Quit @ discription <------------------------*
*@name: void Quit(stringEx&, stringEx&, stringEx&);                           *
*@parameter:stringEx&, stringEx&, stringEx&                                   *
*@purpose: quit the programe                                                  *
*@return value: void                                                          *
*-----------------------------------------------------------------------------*/
void Quit(stringEx &strCI, stringEx &strData, stringEx &strCommand) {
 if (strCommand.GetSubStringNum(DATA_DIVIDER) != 1) {
  AnnounceError(errMsg[ERR_MSG_TOO_MANY_PARAMETERS]);
  return;
 }
 else {
     exit(EXIT_SUCCESS);
 }
}


/*--------------->Function @ ShowColorText @ discription <--------------------*
*@name: void ShowColorText(char *txt, WORD color);                            *
*@parameter: # char *txt  =====>>the text to be shown                         *
# short color  =====>>the color of the text                                   *
*@purpose: show color text                                                    *
*@return value:void                                                           *
*-----------------------------------------------------------------------------*/
void ShowColorText(char *txt, WORD color) {
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
 cout << txt << endl;
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
  FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
}


/*--------------->Function @ ShowDivideLine @ discription <-------------------*
*@name: void ShowDivideLine(bool flag);                                       *
*@parameter: bool flag                                                        *
*@purpose: show dividing line                                                 *
*@return value:void                                                           *
*-----------------------------------------------------------------------------*/
void ShowDivideLine(bool flag) {
 if (flag) {
  for (int i = 0; i < Investigator_Base::WINDOWWIDTH; i++) {
   cout << '-';
  }
 }
 else {
  for (int i = 0; i < Investigator_Base::WINDOWWIDTH; i++) {
   cout << '=';
  }
 }
 cout << endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值