tyvj P1062 merged fool

2023-01-05   ES  

[C ++ Thinking Maps and Code Example] 11 exception processing mechanism

  • Example 1:
/*********************************************** ** 
 ** 
 ** Description: Example: The exception with zero processing 
 Basic ideas of abnormal treatment: 
 In the module that causes abnormalities, it may not be processed. For example, a function H may occur during the operation of the environment or the abnormal failure of the user, which causes the calculation to continue. 
 Function H can not deal with this abnormality. Whoever calls it will throw this abnormality to the callor. This caller can handle abnormalities or continue to feedback abnormalities until a certain level, which is specifically used to capture and handle abnormalities. The level. 

 Abnormal interface declaration: 
 • A function explicitly declare the abnormality that may be thrown, which is conducive to the recipient of the function to prepare for abnormal processing 
 • It can list all the abnormal types that the function may throw in the function of the function. 
 • For example: void fun () throw (a, b, c, d); 
 • If there is no abnormal interface statement, this function can throw any type of exception. 
 • Do not throw any types of abnormal functions as follows: void fun () throw (); 

 ** Author: Mu Lingge-WUPKE 
 ** Time: 2022-1-10 
 ** versions: 11-1.cpp 
 ** 
 * 
 *************************************************** */

#include<iostream>

using namespace std;

int divide(int x, int y){
    
    if (y==0)
        throw x;  // The reminder value when throwing an abnormality
    return x/y; // Otherwise, there is no abnormality, returning normal values
}
int main(){
    
    try
    {
    
        cout<<" 5/2  = " << divide(5,2) <<  endl; 
        cout<<" 6/0  = " << divide(6,0) <<  endl;    
        cout<<" 7/3  = " << divide(7,3) <<  endl;     
    }
    catch(int e)   // Note the form of abnormal capture
    {
    
        cout << e << " is divided by zero !!!" << endl;
    }
    cout << " That is ook. " << endl;
 
    system("pause");
    return  0;
}


  • Example 2:
/ *********************************************** ** 
 ** 
 ** Description: Example: C ++ abnormal processing mechanism with a class semantic class 
 After abnormal throwing, the object that can be treated in the future will still be destructed 

 ** Author: Mu Lingge-WUPKE 
 ** Time: 2022-1-10 
 ** versions: 11-2.cpp 
 ** 
 * 
 *************************************************** */
#include <iostream>
#include <string>

using namespace std;

class MyException {
      // Definition class
public:
    MyException(const string &message) : message(message) {
    } 
    ~MyException() {
    }  // Device
    const string &getMessage() const {
     return message; }
private:
    string message;
};

class Demo {
    
public:
    Demo() {
     cout << "Constructor of Demo" << endl; }  // Construction function
    ~Demo() {
     cout << "Destructor of Demo" << endl; }  // Discirate function
};

void func() throw (MyException) {
    
    Demo d;
    cout << "Throw MyException in func()" << endl;
    throw MyException("exception thrown by func()");
}

int main() {
    
    cout << "In main function" << endl;
    try {
    
        func();
    } catch (MyException& e) {
    
        cout << "Caught an exception: " << e.getMessage() << endl;
    } 
    cout << "Resume the execution of main()" << endl;

    
    return 0;
}

/* 
 operation result: 
 In main function 
 Constructor of demo 
 Throw MyException in Func () 
 Destructor of demo // can be seen that after abnormal throwing, the object of the destruction will still be destructed in the future 
 CAUGHT An Exception: Exception Thrown by Func () 
 Resume the execution of main () 
 */

  • Example 3:
/******************************************************************************************************************************************************************************************************************************, ** 
 ** 
 ** Description: Triangle area calculation 

 ** Author: Mu Lingge-WUPKE 
 ** Time: 2022-1-10 
 ** versions: 11-3.cpp 
 ** 
 * 
 *************************************************** */
#include <iostream>
#include <cmath>
#include <stdexcept>
using namespace std;

// Give triangular three sides, calculate the triangle area
double area(double a, double b, double c) {
    
	// Judging whether the triangular edge length is positive
	if (a <= 0 || b <= 0 || c <= 0)
		throw invalid_argument("the side length should be positive");  
	// Determine whether the three sides meet the Triangle Unilateral
	if (a + b <= c || b + c <= a || c + a <= b)
		throw invalid_argument("the side length should fit the triangle inequality");
	// Calculate the triangular area by Heron formula
	double s = (a + b + c) / 2;
	return sqrt(s * (s - a) * (s - b) * (s - c));
}

int main() {
    
	double a, b, c;	// Triangular three sides long
	cout << "Please input the side lengths of a triangle: ";
	cin >> a >> b >> c;

	try {
    
		double s = area(a, b, c);	// Try to calculate the triangle area
		cout << "Area: " << s << endl;
	} catch (exception &e) {
      // If there is, the capture is abnormal
		cout << "Error: " << e.what() << endl;
	}

    system("pause");
	return 0;
}

  • Example 4:
/**************************************************************************************************************************************************************************************************, ** 
 ** 
 ** Description: 

 Declarse an abnormal class CEXCEPTION, a member function REASON0, 
 It is used to display abnormal types, triggers abnormalities in sub -functions, process abnormalities in the main program, and observe the execution process of the program. 

 ** Author: Mu Lingge-WUPKE 
 ** Time: 2022-1-10 
 ** versions: 11-4.cpp 
 ** 
 * 
 *************************************************** */
#include <iostream>

using namespace std;

class CException
{
    
public:
	CException() {
    }
    virtual ~CException() {
    }
	void Reason() {
    cout << "CException" << endl;}  // In the CEXCEUON class member function REASON), use COUT to display an abnormal type
};

void fn1()
{
    
	throw CException();  // Use the Throw statement to trigger abnormalities in the function fn1 (), that is, Throw Cexception ();
}


int main()
{
    
	try {
    
		fn1();
	} catch (CException& ce) {
     // Capture abnormalities in the CATCH module, capture the abnormalities of the CEXCEPTION class: Ecatch (CEXCEPTION & CE);
		ce.Reason();  
    }

    system("pause");
	return 0;
}

// The treatment after capturing in this example is the cause of the exception: CE.Reason ();

  • Example 5:
/*****************************************************************************************************************************************************************************************************************************, ** 
 ** 
 ** Description: Comprehensive Example: Personal Bank Account Program 
     Improvement: The input of handling users does not meet the requirements: the wrong date query, the quota exceeds, etc. 
          Throw abnormally in the place where the wrong place is detected. The main function is uniformly processed to these abnormalities 
     in: 
 · If there is an error occurred when constructing or entering a Date object 
 · Direct use of the runtime_eror constructor in the standard program library and throw it out 
 ·#Include <stdexcept> 
 · Using the Runtime_ERROR constructor in the standard program library and throw it out 


 · If an error occurs in the account category, because I hope that the abnormal information can indicate which account is wrong, so: 
 · In this program, a class is created. 
 · This class is derived from Runtime_error, 
 · In this class, a ACCOUNT regular pointer is preserved, pointing to an error account, 
 · In the main function, the account can also output the account while output error information. 

 The program is divided into 6 files: 

 Data.h Date -Class header file 
 Accumulator.h head file of the value of the value of the value of the value of the value of the value 
 ACCOUNT.H header file defined by each account class 
 Data.cpp Date -Class Implementation File 
 Files implemented by each account class of account.cpp 
 Mian.cpp the main function of the main function of the main function 

 ** Author: Mu Lingge-WUPKE 
 ** Time: 2022-1-10 
 ** versions: 11-5.cpp 
 ** 
 * 
 *************************************************** */

//date.h
#ifndef __DATE_H__
#define __DATE_H__
#include <iostream>

class Date {
    	// Date
private:
	int year;		//
	int month;		// month
	int day;		// Day
	int totalDays;	// This date is the first day from January 1, the first year of the first year of the first year

public:
	Date(int year = 1, int month = 1, int day = 1);	// construction date with the year, month, and day
	int getYear() const {
     return year; }
	int getMonth() const {
     return month; }
	int getDay() const {
     return day; }
	int getMaxDay() const;		// How many days are there in the month
	bool isLeapYear() const {
    	// Judging whether it was a leap year that year
		return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
	}
	// How many days are the difference between two dates?
	int operator - (const Date& date) const {
    
		return totalDays - date.totalDays;
	}
	// Determine the order of the two dates
	bool operator < (const Date& date) const {
    
		return totalDays < date.totalDays;
	}
};

std::istream & operator >> (std::istream &in, Date &date);
std::ostream & operator << (std::ostream &out, const Date &date);
#endif //__DATE_H__
//date.h
#ifndef __DATE_H__
#define __DATE_H__
#include <iostream>

class Date {
    	// Date
private:
	int year;		//
	int month;		// month
	int day;		// Day
	int totalDays;	// This date is the first day from January 1, the first year of the first year of the first year

public:
	Date(int year = 1, int month = 1, int day = 1);	// construction date with the year, month, and day
	int getYear() const {
     return year; }
	int getMonth() const {
     return month; }
	int getDay() const {
     return day; }
	int getMaxDay() const;		// How many days are there in the month
	bool isLeapYear() const {
    	// Judging whether it was a leap year that year
		return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
	}
	// How many days are the difference between two dates?
	int operator - (const Date& date) const {
    
		return totalDays - date.totalDays;
	}
	// Determine the front and back order of two dates
	bool operator < (const Date& date) const {
    
		return totalDays < date.totalDays;
	}
};

std::istream & operator >> (std::istream &in, Date &date);
std::ostream & operator << (std::ostream &out, const Date &date);
#endif //__DATE_H__





//date.cpp
#include "date.h"
#include <iostream>
#include <stdexcept>
using namespace std;

namespace {
    	// namespace makes the following definition only effective in the current file
	// How many days before the storage year before the first month of the year, in order to facilitate the implementation of the getMaxDay function, there is one more.
	const int DAYS_BEFORE_MONTH[] = {
     0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
}

Date::Date(int year, int month, int day) : year(year), month(month), day(day) {
    
	if (day <= 0 || day > getMaxDay())
		throw runtime_error("Invalid date");
	int years = year - 1;
	totalDays = years * 365 + years / 4 - years / 100 + years / 400
		+ DAYS_BEFORE_MONTH[month - 1] + day;
	if (isLeapYear() && month > 2) totalDays++;
}

int Date::getMaxDay() const {
    
	if (isLeapYear() && month == 2)
		return 29;
	else
		return DAYS_BEFORE_MONTH[month]- DAYS_BEFORE_MONTH[month - 1];
}

istream & operator >> (istream &in, Date &date) {
    
	int year, month, day;
	char c1, c2;
	in >> year >> c1 >> month >> c2 >> day;
	if (c1 != '-' || c2 != '-')
		throw runtime_error("Bad time format");
	date = Date(year, month, day);
	return in;
}

ostream & operator << (ostream &out, const Date &date) {
    
	out << date.getYear() << "-" << date.getMonth() << "-" << date.getDay();
	return out;
}






//accumulator.h
#ifndef __ACCUMULATOR_H__
#define __ACCUMULATOR_H__
#include "date.h"

class Accumulator {
    	// Cumulate a certain value on the day by day
private:
	Date lastDate;	// The period when the value was changed last time
	double value;	// The current value of numerical value
	double sum;		// The sum of the daily accumulation
public:
	// Constructors, Date is the date of starting accumulated, value is the initial value
	Accumulator(const Date &date, double value)
		: lastDate(date), value(value), sum(0) {
     }

	// Obtaining the accumulated result of date Date
	double getSum(const Date &date) const {
    
		return sum + value * (date - lastDate);
	}

	// Change the value to value at Date
	void change(const Date &date, double value) {
    
		sum = getSum(date);
		lastDate = date;
		this->value = value;
	}

	// Initialize, turn the date to date, the value becomes value, the accumulator is clear
	void reset(const Date &date, double value) {
    
		lastDate = date;
		this->value = value;
		sum = 0;
	}
};

#endif //__ACCUMULATOR_H__





//account.h
#ifndef __ACCOUNT_H__
#define __ACCOUNT_H__
#include "date.h"
#include "accumulator.h"
#include <string>
#include <map>
#include <istream>
#include <stdexcept>

class Account;	// Pre -pre -declaration

class AccountRecord {
    	// account record
private:
	Date date;				// Date
	const Account *account;	// account
	double amount;			// amount
	double balance;			// balance
	std::string desc;		// Description
public:
	// Construction function
	AccountRecord(const Date &date, const Account *account, double amount, double balance, const std::string& desc);
	void show() const;	// Output the current record
};

// Define multiple mapping types used to store account records
typedef std::multimap<Date, AccountRecord> RecordMap;

class Account {
     // account class
private:
	std::string id;	// account number
	double balance;	// balance
	static double total; // Total amount of all accounts
	static RecordMap recordMap;	// account records
protected:
	// Construction function for calling classification, ID is an account
	Account(const Date &date, const std::string &id);
	// Record a account, date is the date, amount is the amount, desc
	void record(const Date &date, double amount, const std::string &desc);
	// Report error message
	void error(const std::string &msg) const;
public:
	const std::string &getId() const {
     return id; }
	double getBalance() const {
     return balance; }
	static double getTotal() {
     return total; }
	// deposit in cash, date is the date, amount is amount, desc is a payment description
	virtual void deposit(const Date &date, double amount, const std::string &desc) = 0;
	// Remove the cash, date is the date, amount is amount, desc is a payment description
	virtual void withdraw(const Date &date, double amount, const std::string &desc) = 0;
	// Settlement (calculating interest, annual fee, etc.), settle once a month, date is the settlement date
	virtual void settle(const Date &date) = 0;
	// Display account information
	virtual void show(std::ostream &out) const;
	// Inquiry within the specified time
	static void query(const Date& begin, const Date& end);
};

inline std::ostream & operator << (std::ostream &out, const Account &account) {
    
	account.show(out);
	return out;
}

class SavingsAccount : public Account {
     // savings account category
private:
	Accumulator acc;	// Auxiliary calculation of the accumulator of interest
	double rate;		// The annual interest rate of deposits
public:
	// Construction function
	SavingsAccount(const Date &date, const std::string &id, double rate);
	double getRate() const {
     return rate; }
	virtual void deposit(const Date &date, double amount, const std::string &desc);
	virtual void withdraw(const Date &date, double amount, const std::string &desc);
	virtual void settle(const Date &date);
};

class CreditAccount : public Account {
     // Credit account category
private:
	Accumulator acc;	// Auxiliary calculation of the accumulator of interest
	double credit;		// Credit limit
	double rate;		// The yield of the arrears
	double fee;			// Credit card annual fee

	double getDebt() const {
    	// Get the arrears
		double balance = getBalance();
		return (balance < 0 ? balance : 0);
	}
public:
	// Construction function
	CreditAccount(const Date &date, const std::string &id, double credit, double rate, double fee);
	double getCredit() const {
     return credit; }
	double getRate() const {
     return rate; }
	double getFee() const {
     return fee; }
	double getAvailableCredit() const {
    	// Obtain available credit
		if (getBalance() < 0) 
			return credit + getBalance();
		else
			return credit;
	}
	virtual void deposit(const Date &date, double amount, const std::string &desc);
	virtual void withdraw(const Date &date, double amount, const std::string &desc);
	virtual void settle(const Date &date);
	virtual void show(std::ostream &out) const;
};

class AccountException : public std::runtime_error {
    
private:
	const Account *account;
public:
	AccountException(const Account *account, const std::string &msg)
		: runtime_error(msg), account(account) {
     }
	const Account *getAccount() const {
     return account; }
};
#endif //__ACCOUNT_H__






//account.cpp
#include "account.h"
#include <cmath>
#include <iostream>
#include <utility>
using namespace std;
using namespace std::rel_ops;

// Acountrecord class implementation
AccountRecord::AccountRecord(const Date &date, const Account *account, double amount, double balance, const std::string& desc)
	: date(date), account(account), amount(amount), balance(balance), desc(desc) {
     }

void AccountRecord::show() const {
    
	cout << date << "\t#" << account->getId() << "\t" << amount << "\t" << balance << "\t" << desc << endl;
}

// ACCOUNT class implementation
double Account::total = 0;
RecordMap Account::recordMap;
Account::Account(const Date &date, const string &id)
	: id(id), balance(0) {
    
	cout << date << "\t#" << id << " created" << endl;
}

void Account::record(const Date &date, double amount, const string &desc) {
    
	amount = floor(amount * 100 + 0.5) / 100;	// Reserve two digits after the decimal point
	balance += amount;
	total += amount;
	AccountRecord record(date, this, amount, balance, desc);
	recordMap.insert(make_pair(date, record));
	record.show();
}

void Account::show(ostream &out) const {
    
	out << id << "\tBalance: " << balance;
}

void Account::error(const string &msg) const {
    
	throw AccountException(this, msg);
}

void Account::query(const Date& begin, const Date& end) {
    
	if (begin <= end) {
    
		RecordMap::iterator iter1 = recordMap.lower_bound(begin);
		RecordMap::iterator iter2 = recordMap.upper_bound(end);
		for (RecordMap::iterator iter = iter1; iter != iter2; ++iter)
			iter->second.show();
	}
}

// SAVINGSACCOUNT Class Related Member Function Implementation
SavingsAccount::SavingsAccount(const Date &date, const string &id, double rate)
	: Account(date, id), rate(rate), acc(date, 0) {
     }

void SavingsAccount::deposit(const Date &date, double amount, const string &desc) {
    
	record(date, amount, desc);
	acc.change(date, getBalance());
}

void SavingsAccount::withdraw(const Date &date, double amount, const string &desc) {
    
	if (amount > getBalance()) {
    
		error("not enough money");
	} else {
    
		record(date, -amount, desc);
		acc.change(date, getBalance());
	}
}

void SavingsAccount::settle(const Date &date) {
    
	if (date.getMonth() == 1) {
    	// Calculate interest once a year
		double interest = acc.getSum(date) * rate
			/ (date - Date(date.getYear() - 1, 1, 1));
		if (interest != 0)
			record(date, interest, " interest");
		acc.reset(date, getBalance());
	}
}

// Creditaccount Class Related Member Function Implementation
CreditAccount::CreditAccount(const Date& date, const string& id, double credit, double rate, double fee)
	: Account(date, id), credit(credit), rate(rate), fee(fee), acc(date, 0) {
     }

void CreditAccount::deposit(const Date &date, double amount, const string &desc) {
    
	record(date, amount, desc);
	acc.change(date, getDebt());
}

void CreditAccount::withdraw(const Date &date, double amount, const string &desc) {
    
	if (amount - getBalance() > credit) {
    
		error("not enough credit");
	} else {
    
		record(date, -amount, desc);
		acc.change(date, getDebt());
	}
}

void CreditAccount::settle(const Date &date) {
    
	double interest = acc.getSum(date) * rate;
	if (interest != 0)
		record(date, interest, " interest");
	if (date.getMonth() == 1)
		record(date, -fee, " annual fee");
	acc.reset(date, getDebt());
}

void CreditAccount::show(ostream &out) const {
    
	Account::show(out);
	out << "\tAvailable credit:" << getAvailableCredit();
}






//Main.cpp
#include "account.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

struct deleter {
    
	template <class T> void operator () (T* p) {
     delete p; }
};

class Controller {
    	// The controller, used to store the list of accounts and processing commands
private:
	Date date;					// The current date
	vector<Account *> accounts;	// Account List
	bool end;					// Whether the user entered the exit command

public:
	Controller(const Date &date) : date(date), end(false) {
     }
	~Controller();
	const Date &getDate() const {
     return date; }
	bool isEnd() const {
     return end; }
	// execute a name, whether the command changes the current state (that is, whether the command needs to be saved)
	bool runCommand(const string &cmdLine);
};
Controller::~Controller() {
    
	for_each(accounts.begin(), accounts.end(), deleter());
}
bool Controller::runCommand(const string &cmdLine) {
    
	istringstream str(cmdLine);
	char cmd, type;
	int index, day;
	double amount, credit, rate, fee;
	string id, desc;
	Account* account;
	Date date1, date2;

	str >> cmd;
	switch (cmd) {
    
	case 'a':	// Add account
		str >> type >> id;
		if (type == 's') {
    
			str >> rate;
			account = new SavingsAccount(date, id, rate);
		} else {
    
			str >> credit >> rate >> fee;
			account = new CreditAccount(date, id, credit, rate, fee);
		}
		accounts.push_back(account);
		return true;
	case 'd':	// deposit in cash
		str >> index >> amount;
		getline(str, desc);
		accounts[index]->deposit(date, amount, desc);
		return true;
	case 'w':	// Take out cash
		str >> index >> amount;
		getline(str, desc);
		accounts[index]->withdraw(date, amount, desc);
		return true;
	case 's':	// Query each account information
		for (size_t i = 0; i < accounts.size(); i++)
			cout << "[" << i << "] " << *accounts[i] << endl;
		return false;
	case 'c':	// Change Date
		str >> day;
		if (day < date.getDay())
			cout << "You cannot specify a previous day";
		else if (day > date.getMaxDay())
			cout << "Invalid day";
		else
			date = Date(date.getYear(), date.getMonth(), day);
		return true;
	case 'n':	// Enter the next month
		if (date.getMonth() == 12)
			date = Date(date.getYear() + 1, 1, 1);
		else
			date = Date(date.getYear(), date.getMonth() + 1, 1);
		for (vector<Account*>::iterator iter = accounts.begin(); iter != accounts.end(); ++iter)
			(*iter)->settle(date);
		return true;
	case 'q':	// Query account for a period of time
		str >> date1 >> date2;
		Account::query(date1, date2);
		return false;
	case 'e':	// Exit
		end = true;
		return false;
	}
	cout << "Inavlid command: " << cmdLine << endl;
	return false;
}

int main() {
    
	Date date(2008, 11, 1);	// Starting date
	Controller controller(date);
	string cmdLine;
	const char *FILE_NAME = "commands.txt";

	ifstream fileIn(FILE_NAME);	// Open the file with reading mode
	if (fileIn) {
    	// If you open it normally, perform every command in the file
		while (getline(fileIn, cmdLine)) {
    
			try {
    
				controller.runCommand(cmdLine);
			} catch (exception &e) {
    
				cout << "Bad line in " << FILE_NAME << ": " << cmdLine << endl;
				cout << "Error: " << e.what() << endl;
				return 1;
			}
		}
		fileIn.close();	// Close the file
	}
	
	ofstream fileOut(FILE_NAME, ios_base::app);	// to add mode
	cout << "(a)add account (d)deposit (w)withdraw (s)show (c)change day (n)next month (q)query (e)exit" << endl;
	while (!controller.isEnd()) {
    	// Read the command and execute from the standard input until exit
		cout << controller.getDate() << "\tTotal: " << Account::getTotal() << "\tcommand> ";
		string cmdLine;
		getline(cin, cmdLine);
		try {
    
			if (controller.runCommand(cmdLine))
				fileOut << cmdLine << endl;	// Write the command to the file
		} catch (AccountException &e) {
    
			cout << "Error(#" << e.getAccount()->getId() << "): " << e.what() << endl;
		} catch (exception &e) {
    
			cout << "Error: " << e.what() << endl;
		}
	}
	return 0;
}



  • Example 6:



  • Example 7:



  • Example 8:



  • Example 9:



source

Related Posts

Use NUXT restructuring existing Vue project (AXIOS default root domain name, switch Vuetify font, configure MAVON editor, and common abnormal solution to LocalStorage/Window/Document is not defined) Piconjo

javascript variable keywords and retention words

“In -depth understanding OSGI: Equinox Principles, Application and Best Practice” Notes 2 Establish a development environment

Japan search engine Daquan

tyvj P1062 merged fool

Random Posts

[Simple filter algorithm] Common filtering algorithm explanation and routine

R language cluster analysis-KMEANS cluster analysis actual combat

UNI-APP Implementation Verification Code Login-Cloud News Stitch

EJB3 Getting Started Example

Baidu Publish input Method 8.0 Huaxian 58 seconds 426 words are correctly identified | News