vs集積qtは簡単な計算機を実現する


すべての状況を考慮していないかもしれませんが、基本的な計算はできます!
Calculator.h
#pragma once

#include 
#include "ui_Calculator.h"
#include "calculation.h"
#include 
#include 
#include 
#include 

const int TOTALNUM = 10; //      
const int OPERATORNUM = 6; //      
const int WIDTH = 300; //       
const int HEIGHT = 450; //       
const int ZOOMINWIDTH = 600; //              

const int BUTTONWIDTH = 60; //      
const int BUTTONHEIGHT = 40; //      

const int SMALLBUTTONWIDTH = 30; //       
const int SMALLBUTTONHEIGHT = 30; //       

class Calculator : public QDialog
{
	Q_OBJECT

public:
	Calculator(QWidget *parent = Q_NULLPTR);

private:
	Ui::CalculatorClass ui;

private:
	calculation c;

	QPushButton *histotyButton;

	QPushButton *numButton[TOTALNUM];
	QPushButton *operatorButton[OPERATORNUM];
	QPushButton *pointButton;
	QPushButton *leftParenthesesButton;
	QPushButton *rightParenthesesButton;
	QPushButton *sinButton;
	QPushButton *cosButton;
	QPushButton *tanButton;
	QPushButton *sqrtButton;
	QPushButton *squareButton;
	QPushButton *logButton;
	QPushButton *expButton;
	QPushButton *none1;
	QPushButton *none2;
	QPushButton *miciButton;
	QPushButton *tenMiciButton;
	QPushButton *factorialButton;
	QPushButton *positiveAndNegativeButton;
	QPushButton *piButton;
	QPushButton *clearButton;
	QPushButton *backspaceButton;

	QLineEdit *expressionLineEdit;
	QPlainTextEdit *historyResultTextEdit;

private:
	void initButton();
	void setButton(QPushButton * button, const QString & filePath, const int & width, const int & height, const int & buttonWidth = BUTTONWIDTH, const int & buttonHeight = BUTTONHEIGHT);

	void initLineEdit();
	char* getLastNum();

private slots:
	void onNumButtonClicked(const qreal & num);
	void onOperatorButtonClicked(const char & operatorName);
	void backspaceButtonClicked();
	void clearButtonClicked();
	void triFunButtonClicked(const QString & tri);
	void squareButtonClicked();
	void sqrtButtonClicked();
	void powButtonClicked();
	void tenPowButtonClicked();
	void positiveAndNegativeButtonClicked();
	void eFunButtonClicked(const QString & e);
	void histotyButtonClicked();
};

Calculaor.cpp
#include "Calculator.h"

bool zoomin = false; //     (     )

const char OPERATOR[] = "%/*-+=";

Calculator::Calculator(QWidget *parent)
	: QDialog(parent)
{
	ui.setupUi(this);
	//    
	initButton();
	initLineEdit();
}

//       
double factorial(int n) {
	double res = 1;
	while (n > 0) {
		res *= n;
		n--;
	}
	return res;
}

void Calculator::initButton()
{
	setMinimumSize(WIDTH, HEIGHT);
	setMaximumSize(WIDTH, HEIGHT);

	QString iconPath;
	int j = 1;
	int i;
	//        
	for (i = 0; i < TOTALNUM; ++i) {
		numButton[i] = new QPushButton(this);
		iconPath = "./img/num" + QString::number(i) + ".png";
		if (i == 0) {
			setButton(numButton[i], iconPath, (WIDTH - BUTTONWIDTH) >> 1, HEIGHT - BUTTONHEIGHT);
		}
		else {
			if (i % 3 == 1) {
				j++;
			}
			setButton(numButton[i], iconPath, BUTTONWIDTH * ((i - 1) % 3 + 1), HEIGHT - j * BUTTONHEIGHT);
		}
		//   lamda       
		connect(numButton[i], &QPushButton::clicked, this, [=] {onNumButtonClicked(i); });
	}

	//                 
	for (i = 0; i < OPERATORNUM; ++i) {
		operatorButton[i] = new QPushButton(this);
		iconPath = "./img/operator" + QString::number(i + 1) + ".png";
		setButton(operatorButton[i], iconPath, WIDTH - BUTTONWIDTH, HEIGHT - BUTTONHEIGHT * (OPERATORNUM - i));
		connect(operatorButton[i], &QPushButton::clicked, this, [=] {onOperatorButtonClicked(OPERATOR[i]); });
	}

	//         
	pointButton = new QPushButton(this);
	setButton(pointButton, "./img/point.png", WIDTH - BUTTONWIDTH * 2, HEIGHT - BUTTONHEIGHT);
	connect(pointButton, &QPushButton::clicked, this, [=] {onOperatorButtonClicked('.'); });

	//         
	leftParenthesesButton = new QPushButton(this);
	setButton(leftParenthesesButton, "./img/leftParentheses.png", 0, HEIGHT - BUTTONHEIGHT);
	connect(leftParenthesesButton, &QPushButton::clicked, this, [=] {onOperatorButtonClicked('('); });


	//         
	rightParenthesesButton = new QPushButton(this);
	setButton(rightParenthesesButton, "./img/rightParentheses.png", BUTTONWIDTH, HEIGHT - BUTTONHEIGHT);
	connect(rightParenthesesButton, &QPushButton::clicked, this, [=] {onOperatorButtonClicked(')'); });


	//          
	sinButton = new QPushButton(this);
	cosButton = new QPushButton(this);
	tanButton = new QPushButton(this);
	setButton(sinButton, "./img/sin.png", WIDTH - 3 * BUTTONWIDTH, HEIGHT - 7 * BUTTONHEIGHT);
	setButton(cosButton, "./img/cos.png", WIDTH - 2 * BUTTONWIDTH, HEIGHT - 7 * BUTTONHEIGHT);
	setButton(tanButton, "./img/tan.png", WIDTH - BUTTONWIDTH, HEIGHT - 7 * BUTTONHEIGHT);
	connect(sinButton, &QPushButton::clicked, this, [=] {triFunButtonClicked("sin"); });
	connect(cosButton, &QPushButton::clicked, this, [=] {triFunButtonClicked("cos"); });
	connect(tanButton, &QPushButton::clicked, this, [=] {triFunButtonClicked("tan"); });

	//          
	sqrtButton = new QPushButton(this);
	squareButton = new QPushButton(this);
	setButton(sqrtButton, "./img/sqrt.png", 0, HEIGHT - 6 * BUTTONHEIGHT);
	setButton(squareButton, "./img/square.png", 0, HEIGHT - 7 * BUTTONHEIGHT);
	connect(sqrtButton, SIGNAL(clicked()), this, SLOT(sqrtButtonClicked()));
	connect(squareButton, SIGNAL(clicked()), this, SLOT(squareButtonClicked()));

	//               
	logButton = new QPushButton(this);
	expButton = new QPushButton(this);
	setButton(logButton, "./img/log.png", WIDTH - 3 * BUTTONWIDTH, HEIGHT - 6 * BUTTONHEIGHT);
	setButton(expButton, "./img/exp.png", WIDTH - 2 * BUTTONWIDTH, HEIGHT - 6 * BUTTONHEIGHT);
	connect(logButton, &QPushButton::clicked, this, [=] {eFunButtonClicked("log"); });
	connect(expButton, &QPushButton::clicked, this, [=] {eFunButtonClicked("exp"); });

	//           
	none1 = new QPushButton(this);
	none2 = new QPushButton(this);
	setButton(none1, "./img/none1.png", 0, HEIGHT - 5 * BUTTONHEIGHT);
	setButton(none2, "./img/none2.png", BUTTONWIDTH, HEIGHT - 5 * BUTTONHEIGHT);

	//        
	miciButton = new QPushButton(this);
	tenMiciButton = new QPushButton(this);
	setButton(miciButton, "./img/mici.png", BUTTONWIDTH, HEIGHT - 7 * BUTTONHEIGHT);
	setButton(tenMiciButton, "./img/tenMici.png", BUTTONWIDTH, HEIGHT - 6 * BUTTONHEIGHT);
	connect(miciButton, SIGNAL(clicked()), this, SLOT(powButtonClicked()));
	connect(tenMiciButton, SIGNAL(clicked()), this, SLOT(tenPowButtonClicked()));

	//        
	factorialButton = new QPushButton(this);
	setButton(factorialButton, "./img/factorial.png", 0, HEIGHT - 3 * BUTTONHEIGHT);
	connect(factorialButton, &QPushButton::clicked, this, [=] {onOperatorButtonClicked('!'); });

	//            
	positiveAndNegativeButton = new QPushButton(this);
	setButton(positiveAndNegativeButton, "./img/positiveAndNegative.png", 0, HEIGHT - 2 * BUTTONHEIGHT);
	connect(positiveAndNegativeButton, SIGNAL(clicked()), this, SLOT(positiveAndNegativeButtonClicked()));

	//    PI  
	piButton = new QPushButton(this);
	setButton(piButton, "./img/pi.png", 0, HEIGHT - 4 * BUTTONHEIGHT);
	connect(piButton, &QPushButton::clicked, this, [=] {onNumButtonClicked(3.14); });

	//        
	clearButton = new QPushButton(this);
	setButton(clearButton, "./img/clear.png", WIDTH - 3 * BUTTONWIDTH, HEIGHT - 5 * BUTTONHEIGHT);
	connect(clearButton, SIGNAL(clicked()), this, SLOT(clearButtonClicked()));

	//        
	backspaceButton = new QPushButton(this);
	setButton(backspaceButton, "./img/backspace.png", WIDTH - 2 * BUTTONWIDTH, HEIGHT - 5 * BUTTONHEIGHT);
	connect(backspaceButton, SIGNAL(clicked()), this, SLOT(backspaceButtonClicked()));

	//            
	histotyButton = new QPushButton(this);
	setButton(histotyButton, "./img/history.png", 0, 0, SMALLBUTTONWIDTH, SMALLBUTTONHEIGHT);
	connect(histotyButton, SIGNAL(clicked()), this, SLOT(histotyButtonClicked()));

}

//     
//           BUTTONWIDTH(60)   BUTTONHEIGHT(40)
void Calculator::setButton(QPushButton * button, const QString & filePath
	, const int & width, const int & height
	, const int & buttonWidth, const int & buttonHeight)
{
	button->setGeometry(width, height, buttonWidth, buttonHeight);
	button->setIcon(QIcon(filePath));
	button->setIconSize(QSize(buttonWidth, buttonHeight));
}

//             
void Calculator::initLineEdit()
{
	expressionLineEdit = new QLineEdit(this);
	expressionLineEdit->setGeometry(0, HEIGHT - 9 * BUTTONHEIGHT, WIDTH, BUTTONHEIGHT);
	expressionLineEdit->setFont(QFont("    ", 24)); //     
	expressionLineEdit->setReadOnly(true); //        

	historyResultTextEdit = new QPlainTextEdit(this);
	historyResultTextEdit->setGeometry(WIDTH, 0, ZOOMINWIDTH - WIDTH, HEIGHT);
	historyResultTextEdit->setFont(QFont("    ", 24)); //     
	historyResultTextEdit->setReadOnly(true); //        
}

//         (              )
char* Calculator::getLastNum()
{
	std::string s = expressionLineEdit->text().toStdString();
	size_t length = strlen(s.c_str());
	char res[NUMSIZE];
	memset(res, '\0', NUMSIZE);
	/*
	 *    :
	 *        
	 *          (+,-)    e
	 *                      
	 */
	for (int i = length - 1; i >= 0
		&& (!c.isOperator(s[i])
			|| (c.isOperator(s[i]) && (0 == i || 'e' == s[i - 1]))
			|| ('-' == s[i] && (i == 0 || c.isOperator(s[i - 1])))); --i) {
		strcpy(res, strcat(ctocstar(s[i]), res));
		expressionLineEdit->backspace();
	}
	return res;
}

//        
void Calculator::onNumButtonClicked(const qreal & num)
{
	std::string tempStr = expressionLineEdit->text().toStdString();
	// PI      
	//      , PI           
	if (3.14 == num && "" != tempStr
		&& (!c.isOperator(tempStr.back())
			|| ')' == tempStr.back())) {
		expressionLineEdit->setText(expressionLineEdit->text() + '*' + QString::number(num));
	}
	else {
		expressionLineEdit->setText(expressionLineEdit->text() + QString::number(num));
	}
}

void Calculator::onOperatorButtonClicked(const char & operatorName)
{
	std::string tempStr = expressionLineEdit->text().toStdString();
	/*
	 *         
	 *          
	 *                
	 *         
	 */
	if ('=' == operatorName) {
		if ("" == expressionLineEdit->text()) {
			QMessageBox::information(NULL, "warning!", "you can't do this!");
			return;
		}
		if (c.isOperator(tempStr.back())) {
			if (')' != tempStr.back()) {
				QMessageBox::information(NULL, "warning!", "you can't put a single operator at the end!");
				return;
			}
		}
		double res = c.calculate(tempStr.c_str());
		if (WRONGTAG == res) {
			expressionLineEdit->clear();
		}
		else {
			historyResultTextEdit->setPlainText(expressionLineEdit->text() 
				+ '=' 
				+ QString::number(res) 
				+ '
' + historyResultTextEdit->toPlainText()); expressionLineEdit->setText(QString::number(res)); } } // else if ('!' == operatorName) { char* res = new char[NUMSIZE]; strcpy(res, getLastNum()); double d = c.stod(res); expressionLineEdit->setText(expressionLineEdit->text() + QString::number(factorial(d))); } // else if ('.' == operatorName) { if ("" != tempStr && !c.isOperator(tempStr.back()) && '.' != tempStr.back()) { expressionLineEdit->setText(expressionLineEdit->text() + '.'); } } /* * * * ( ')') */ else if ('(' == operatorName) { if ("" != expressionLineEdit->text() && !c.isOperator(tempStr.back())) { expressionLineEdit->setText(expressionLineEdit->text() + '*'); } expressionLineEdit->setText(expressionLineEdit->text() + operatorName); } else if ("" == expressionLineEdit->text() && '-' == operatorName) { expressionLineEdit->setText(expressionLineEdit->text() + operatorName); } else if(("" != expressionLineEdit->text() && (!c.isOperator(tempStr.back()) && '.' != tempStr.back() || ')' == tempStr.back()))){ expressionLineEdit->setText(expressionLineEdit->text() + operatorName); } } void Calculator::backspaceButtonClicked() { expressionLineEdit->backspace(); } void Calculator::clearButtonClicked() { expressionLineEdit->clear(); } void Calculator::triFunButtonClicked(const QString & tri) { char* res = new char[NUMSIZE]; strcpy(res, getLastNum()); double d = c.stod(res); if ("sin" == tri) { expressionLineEdit->setText(expressionLineEdit->text() + QString::number(sin(d))); } else if ("cos" == tri) { expressionLineEdit->setText(expressionLineEdit->text() + QString::number(cos(d))); } else if ("tan" == tri) { expressionLineEdit->setText(expressionLineEdit->text() + QString::number(tan(d))); } } void Calculator::squareButtonClicked() { char* res = new char[NUMSIZE]; strcpy(res, getLastNum()); double d = c.stod(res); expressionLineEdit->setText(expressionLineEdit->text() + QString::number(pow(d, 2))); } void Calculator::sqrtButtonClicked() { char* res = new char[NUMSIZE]; strcpy(res, getLastNum()); double d = c.stod(res); expressionLineEdit->setText(expressionLineEdit->text() + QString::number(pow(d, 0.5))); } void Calculator::powButtonClicked() { expressionLineEdit->setText(expressionLineEdit->text() + "^"); } void Calculator::tenPowButtonClicked() { std::string tempStr = expressionLineEdit->text().toStdString(); // PI if ("" != tempStr && (!c.isOperator(tempStr.back()) || ')' == tempStr.back())) { expressionLineEdit->setText(expressionLineEdit->text() + '*'); } expressionLineEdit->setText(expressionLineEdit->text() + "10^"); } void Calculator::positiveAndNegativeButtonClicked() { // do nothing } void Calculator::eFunButtonClicked(const QString & e) { char* res = new char[NUMSIZE]; strcpy(res, getLastNum()); double d = c.stod(res); if ("exp" == e) { expressionLineEdit->setText(expressionLineEdit->text() + QString::number(exp(d))); } else if ("log" == e) { if (d <= 0) { QMessageBox::information(NULL, "warning!", "you can't use this number as the base"); expressionLineEdit->clear(); } else { expressionLineEdit->setText(expressionLineEdit->text() + QString::number(log(d))); } } } void Calculator::histotyButtonClicked() { if (false == zoomin) { setMinimumSize(ZOOMINWIDTH, HEIGHT); setMaximumSize(ZOOMINWIDTH, HEIGHT); zoomin = true; } else if (true == zoomin) { setMinimumSize(WIDTH, HEIGHT); setMaximumSize(WIDTH, HEIGHT); zoomin = false; } }

calculation.h
#pragma once
#include "vector.h"
#include "stack.h"
#include 


const int NUMSIZE = 20; //          
const int WRONGTAG = -INT_MAX; //     


class calculation {
public:
	double stod(char* s);
	bool isOperator(const char c);
	double calculate(const char* expressions);
};

char* ctocstar(char c);

calculation.cpp
#pragma warning(disable:4996)
#include "calculation.h"

const char* operators = "+-*/%()^";


//      
int icp(const char c)
{
	switch (c)
	{
	case '(':return 6;
	case '*':
	case '/':
	case '^':
	case '%':return 4;
	case '+':
	case '-':return 2;
	case ')':return 1;
	default:break;
	}
	return 0;
}

//      
int isp(const char c)
{
	switch (c)
	{
	case '(':return 1;
	case '*':
	case '/':
	case '^':
	case '%':return 5;
	case '+':
	case '-':return 3;
	case ')':return 6;
	default:break;
	}
	return 0;
}

//          
double calculation::stod(char * s)
{
	double res = 0;
	bool isNegative = s[0] == '-' ? true : false; //        
	int i = 0;
	int size = 0; //     ( e  )
	int ePos = -1; //   e   ,        -1
	int pointPos = -1; //         ,        -1
	for (i = isNegative; s[i] != '\0'; ++i) {
		if (s[i] == '.') {
			pointPos = i;
			size++;
		}
		else if (s[i] == 'e') {
			ePos = i;
			break;
		}
		else {
			size++;
		}
	}
	//     
	for (i = isNegative; i < size + isNegative; ++i) {
		if (i == pointPos) {
			continue;
		}
		res = res * 10 + (s[i] - '0');
	}
	if (-1 != pointPos) {
		while (size != pointPos + 1) {
			res = res / 10;
			size--;
		}
	}
	//       
	if (-1 != ePos) {
		int exponential = 0; //     
		bool isNegativeExp = s[ePos + 1] == '-' ? true : false; //            
		for (i = ePos + 2; s[i] != '\0'; ++i) {
			exponential = exponential * 10 + (s[i] - '0');
		}
		if (isNegativeExp) {
			while (exponential--) {
				res /= 10;
			}
		}
		else {
			while (exponential--) {
				res *= 10;
			}
		}
	}
	return isNegative ? -res : res;
}

bool calculation::isOperator(const char c)
{
	for (int i = 0; operators[i] != '\0'; ++i) {
		if (c == operators[i]) {
			return true;
		}
	}
	return false;
}

char* ctocstar(const char c) {
	char *ch = new char[2];
	ch[0] = c;
	ch[1] = '\0';
	return ch;
}

double calculation::calculate(const char * expressions)
{
	if ("" == expressions) {
		return WRONGTAG;
	}
	Stack numStack; //       
	Stack symStack; //       
	//               
	char num[NUMSIZE]; //            
	sprintf_s(num, NUMSIZE, "%c", '\0');
	char temp = NULL;
	Vector sufExpressions;
	int i = NULL;
	for (i = 0; expressions[i] != '\0'; ++i) {
		temp = expressions[i];
		//           num 
		//       e     
		if (!isOperator(temp) || (isOperator(temp) && expressions[i - 1] == 'e')) {
			sprintf_s(num, NUMSIZE, "%s%c", num, temp);
		}
		//       
		else {
			char *tempch = new char[NUMSIZE];
			strcpy(tempch, num);
			if (num[0] != '\0') {
				sufExpressions.push_back(tempch); //             
			}
			sprintf_s(num, NUMSIZE, "%c", '\0');
			/*
			 *          
			 *                   
			 *              ,  
			 *            ,    
			 */
			if (')' == temp) {
				//                   ,       
				while (!symStack.empty() && symStack.top() != '(') {
					sufExpressions.push_back(ctocstar(symStack.top()));
					symStack.pop();
				}
				//                
				if (symStack.empty()) {
					QMessageBox::information(NULL, "warning!", "lack of leftparentheses!");
					return WRONGTAG;
				}
				else {
					//       
					symStack.pop();
				}
			}
			else {
				while (!symStack.empty() && (isp(symStack.top()) > icp(temp))) {
					sufExpressions.push_back(ctocstar(symStack.top()));
					symStack.pop();
				}
				symStack.push(temp);
			}
		}
	}
	//         
	if (num[0] != '\0') {
		sufExpressions.push_back(num);
	}
	//           
	while (!symStack.empty()) {
		sufExpressions.push_back(ctocstar(symStack.top()));
		symStack.pop();
	}
	double tempNum1 = NULL, tempNum2 = NULL;
	//        
	for (i = 0; i < sufExpressions.size(); ++i) {
		if (0 == strcmp(sufExpressions[i], "+")) {
			tempNum1 = numStack.top();
			numStack.pop();
			tempNum2 = numStack.top();
			numStack.pop();
			numStack.push(tempNum1 + tempNum2);
		}
		else if (0 == strcmp(sufExpressions[i], "-")) {
			tempNum1 = numStack.top();
			numStack.pop();
			//                    (    )
			if (numStack.empty() || (i < sufExpressions.size() - 1 && isOperator(sufExpressions[i + 1][0]))) {
				tempNum2 = 0;
			}
			else {
				tempNum2 = numStack.top();
				numStack.pop();
			}
			numStack.push(tempNum2 - tempNum1);
		}
		else if (0 == strcmp(sufExpressions[i], "*")) {
			tempNum1 = numStack.top();
			numStack.pop();
			tempNum2 = numStack.top();
			numStack.pop();
			numStack.push(tempNum1 * tempNum2);
		}
		else if (0 == strcmp(sufExpressions[i], "/")) {
			tempNum1 = numStack.top();
			numStack.pop();
			tempNum2 = numStack.top();
			numStack.pop();
			//      0
			if (tempNum1 == 0) {
				QMessageBox::information(NULL, "warning!", "you can't divide zero!");
				return WRONGTAG;
			}
			else {
				numStack.push(tempNum2 / tempNum1);
			}
		}
		else if (0 == strcmp(sufExpressions[i], "%")) {
			tempNum1 = numStack.top();
			numStack.pop();
			tempNum2 = numStack.top();
			numStack.pop();
			//        0     
			if (tempNum2 < 0) {
				numStack.push(tempNum1 + (tempNum2 - (int)(tempNum2 / tempNum1) * tempNum1));
			}
			else {
				numStack.push(tempNum2 - (int)(tempNum2 / tempNum1) * tempNum1);
			}
		}
		else if (0 == strcmp(sufExpressions[i], "^")) {
			tempNum1 = numStack.top();
			numStack.pop();
			tempNum2 = numStack.top();
			numStack.pop();
			numStack.push(pow(tempNum2, tempNum1));
		}
		else if (0 == strcmp(sufExpressions[i], "(")) {
			QMessageBox::information(NULL, "warning!", "lack of rightparenteses!");
			return WRONGTAG;
		}
		else {
			numStack.push(stod(sufExpressions[i]));
		}
	}
	//           0
	if (numStack.empty()) {
		return 0;
	}
	return numStack.top();
}

リンク:https://share.weiyun.com/5A45cgb
画像の素材はリンクの中にあって、マイクロソフトのコンピュータのスクリーンショットです