意表を突いても勝てない

サンムーンでたら頑張る

2

CCalc.cpp

#include <cctype>//isdigit
#include <cmath>// round,fabs
#include <cfloat>//DBL_EPSILON
#include "CCalc2.h"



long  CCalc::getErrorCode() {
	return m_errorCode;
}

double CCalc::calculate() {

	return AddSub();
}

double CCalc::AddSub()
{
	double ans = MulDiv();

	while ((m_errorCode == ERRCODE_SUCCESS) && (m_itr != m_inputString.end())) {
		switch (*m_itr) {
		case '+':
			m_itr++;
			m_ContinuousOperator = true;
			ans += MulDiv();
			m_ContinuousOperator = false;
			break;
		case '-':
			m_itr++;
			m_ContinuousOperator = true;
			ans -= MulDiv();
			m_ContinuousOperator = false;
			break;
		default:
			if (!isdigit(*m_itr) && (*m_itr != '.') && (*m_itr != m_BLKEND)) {//数字の後の数字意外を弾く(例:5g4)
				m_errorCode = ERRCODE_NOT_DIGIT;
			}
			return ans;
			break;

		}
	}
	return ans;
}

double CCalc::MulDiv()
{
	double ans = Factor();
	double div = 0.0; //割る数が0以外かのチェック用
	while ((m_errorCode == ERRCODE_SUCCESS) && (m_itr != m_inputString.end())) {
		switch (*m_itr) {
		case '*':
			m_itr++;
			m_ContinuousOperator = true;
			ans *= Factor();
			m_ContinuousOperator = false;
			break;
		case '/':
			m_itr++;
			m_ContinuousOperator = true;
			div = Factor();
			m_ContinuousOperator = false;
			if (fabs(div - 0.0) < DBL_EPSILON) {//小数なので相対誤差で0かチェック
				m_errorCode = ERRCODE_DIVIDED_ZERO;
				return ans;
			}
			ans /= div;
			break;
		default:
			return ans;
			break;
		}
	}
	return ans;
}

double CCalc::Factor()
{
	double ans = 0.0;

	if ((*m_itr) == m_BLKTOP) {
		m_itr++;
		m_inBlock = true;
		ans = AddSub();
		if ((m_itr == m_inputString.end()) || ((*m_itr) != m_BLKEND)) {
			m_errorCode = ERRCODE_NOT_BLKEND;
			return 0;
		}
		m_itr++;
		m_inBlock = false;
		return ans;
	}

	if (m_inBlock) {
		if (isdigit(*m_itr) || (*m_itr == '.') || (*m_itr == '-')) {
			return Value();
		}
	}
	else {
		if (isdigit(*m_itr) || (*m_itr == '.')) {
			return Value();
		}

	}
	
	if ((m_ContinuousOperator == true) && (((*m_itr == '+')) || ((*m_itr == '-')) || ((*m_itr == '*')) || ((*m_itr == '/')))) {
		m_errorCode = ERRCODE_CONTINUOUS_OPERATOR;
	}
	else {
		m_errorCode = ERRCODE_NOT_DIGIT;
	}
	

	return 0;
}

double CCalc::Value()
{
	double ans = 0.0;
	size_t conversion_i = 0;
	ans = std::stod(&(*m_itr), &conversion_i);
	m_itr += conversion_i;
	ans = round2(ans, m_DEGREE);//入力を5桁に調整
	return ans;
}

double CCalc::round2(double dIn, int nLen)
{
	double    dOut;

	dOut = dIn * pow(10.0, nLen - 1);
	dOut = (double)round(dOut);
	dOut *= pow(10.0, -(nLen - 1));

	return dOut;
}

CCalc.h

#pragma once
#include <string>
using namespace std;

class CCalc
{
public:
	CCalc() = delete;
	CCalc(const string& input) : m_inputString(input), m_errorCode(ERRCODE_SUCCESS) {
		m_itr = m_inputString.begin();
		m_inBlock = false;
		m_ContinuousOperator = false;
	}
	virtual ~CCalc() = default;

	enum eERRCODE {
		ERRCODE_SUCCESS,
		ERRCODE_NOT_DIGIT,
		ERRCODE_DIVIDED_ZERO,
		ERRCODE_NOT_BLKEND,
		ERRCODE_CONTINUOUS_OPERATOR,
	};

	long getErrorCode();
	double calculate();


private:
	const string m_inputString;
	long m_errorCode;
	string::const_iterator m_itr;
	static const int m_DEGREE = 6;//四捨五入をする桁←どこで書くべき?
	static const char m_BLKTOP = '(';
	static const char m_BLKEND = ')';
	bool m_inBlock;
	bool m_ContinuousOperator;
	double AddSub();
	double MulDiv();
	double Factor();
	double Value();
	double round2(double dIn, int nLen);
};



main.cpp

#include <iostream>
#include <iomanip>
#include <string>
#include "CCalc2.h"

using namespace std;

int main(void)
{
	string input;

	while (!cin.eof()) {
		cin >> input;
		if (input != "\0") {

			CCalc calc(input);//new~Deleteにするかセット関数にするか,このままだとインスタンスをずっと生成してしまう?

			double ans = calc.calculate();

			switch (calc.getErrorCode()) {
			case calc.ERRCODE_NOT_DIGIT:
				cout << "ERROR!:NOT_DIGIT" << endl << endl;
				break;
			case calc.ERRCODE_DIVIDED_ZERO:
				cout << "ERROR!:Divided Zero" << endl << endl;
				break;
			case calc.ERRCODE_NOT_BLKEND:
				cout << "ERROR!:Not Block End" << endl << endl;
				break;
			case calc.ERRCODE_CONTINUOUS_OPERATOR:
				cout << "ERROR!CONTINUOUS_OPERATOR" << endl << endl;
				break;
			default:
				cout << fixed << setprecision(5) << ans << endl << endl;//小数点5桁表示
			}
		}
	}
	return 0;
}