C++QT实现计算器<全容错处理>

本文介绍了一种使用C++和QT框架实现的计算器,具备完整的容错处理功能,支持±*/()和小数运算。通过将UI与逻辑分离,利用QString在UI层进行错误检查,只有在无误的情况下才执行计算。计算过程中,中缀表达式转换为后缀表达式,然后通过栈进行计算。小数处理通过在后缀表达式中插入空格来分隔数值。此外,文章还详细说明了各种容错机制,包括小数点、数字、符号、括号的错误检查,并提供了源代码文件的概览。
摘要由CSDN通过智能技术生成

用C++跟QT实现计算器,支持±*/()小数,容错做到极致了?

基本思路:

原理:

UI与逻辑分离,容错利用QString做在UI上,只能在无错情况下进入逻辑,否则按下=无效.
计算利用中缀表达式转为后缀表达式后,入栈进行计算,得到一个数字返回给UI

具体一些:按下=时,如果有效则会将QString转换为string再转char数组,传给逻辑里的change(char[]pre)函数,将其转化为后缀表达式.
接下来就是用calculate(char[]post)后缀表达式的计算啦
小数部分如何实现?:
读取部分有一个post数组存放后缀表达式,和一个栈用来存放符号,读到一个数时会一直往后读到符号前,然后数组里加入一个空格用来分隔数.下一个是符号则先放入符号栈.
例如1.2+2#过程:
先向stack里放一个#
读取1 放入post数组,
读到".“放入post数组,
读到"2"放入post数组
读到”+" post数组加入一个空格,由于+优先级大于#优先级故直接加入栈中,否则弹栈符号直到+优先级最大,然后将+加入栈
读取"2"放入post数组
读到"#"停止
符号栈全部取出放入post数组 成功转化为后缀表达式,接下来就是后缀表达式的计算
后缀表达式的计算就比较简单了,读到一个数字,将post数组和该数字的下标地址传入readnumber方法,该方法用于读取数组直到遇见空格或是符号,为了将其转化为小数,然后放入栈中.
读到空格则继续
读到符号则从栈中取出两个数进行计算
遇见#循环停止

容错,

是在UI里大量的IF语句
有:

  • 小数点容错:前一位不是括号符号,当前数字中不含小数点(7.7.7型)

  • 数字容错:不能在)后输入数字,前一位是0的情况要验证小数点,如果没有小数点再验证数字是否首位不为0(01无法输入,但10000,0.00000001可以)

  • 符号容错:符号不能在小数点后面,(后面和首位(-除外,第一位可以放-,只需要在计算时首位加0即可)

  • 括号容错:(上一位不能是数,小数点和) 而)上一位不能是符号,小数点,不能当作首位,且前方有未匹配左括号,可以加入)
    如果上一位是(则添加0后加入)(0)
    与之匹配相互对应,在执行回退一位的时候需要验证是否是()并相应执行±,在清空时将括号匹配count置为0

  • ="容错,前一位是±*/.,且括号全部匹配时,(即count=0)才可计算
    智能优化:在=操作执行后,再次输入数字会清空文本框再输入

  • 目前已知缺陷:数太大情况下放不下,如有其他,请留言我改正

在这里插入图片描述

源代码:

UI界面:

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QStack>
#include <QMainWindow>
#include <QChar>
#include "calculator.h"
class MainWindow : public QMainWindow
{
   
	Q_OBJECT
public:
	MainWindow(QWidget* parent = 0);
private:
	QString s;
	Calculator c;
	void calculate0();
	bool sign_judge(QString s);
	bool point_judge(QString s);
	bool not_type_01_(QString s);
	int count = 0;
	bool clear = false;
};

#endif

mainwindows.cpp:

#include "mainwindow.h"
#include <QPushButton>
#include <QTextEdit>
#include<string.h>
#include <QTextCharFormat>
#include <QFont>

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent) {
   
    //初始化
    s = "";

    resize(510, 510);
    setWindowTitle("CAL");
    //设置按钮,指定父对象
    QPushButton* button_1 = new QPushButton(this);
    QPushButton* button_2 = new QPushButton(this);
    QPushButton* button_3 = new QPushButton(this);
    QPushButton* button_4 = new QPushButton(this);
    QPushButton* button_5 = new QPushButton(this);
    QPushButton* button_6 = new QPushButton(this);
    QPushButton* button_7 = new QPushButton(this);
    QPushButton* button_8 = new QPushButton(this);
    QPushButton* button_9 = new QPushButton(this);
    QPushButton* button_0 = new QPushButton(this);
    QPushButton* button_add = new QPushButton(this);
    QPushButton* button_dec = new QPushButton(this);
    QPushButton* button_mul = new QPushButton(this);
    QPushButton* button_div = new QPushButton(this);
    QPushButton* button_clear = new QPushButton(this);
    QPushButton* button_equal = new QPushButton(this);
    QPushButton* button_point = new QPushButton(this);
    QPushButton* button_left = new QPushButton(this);
    QPushButton* button_right = new QPushButton(this);
    QPushButton* button_delete = new QPushButton(this);

    button_0->setText("0");
    button_1->setText("1");
    button_2->setText("2");
    button_3->setText("3");
    button_4->setText("4");
    button_5->setText("5");
    button_6->setText("6");
    button_7->setText("7");
    button_8->setText("8");
    button_9->setText("9");
    button_add->setText("+");
    button_dec->setText("-");
    button_mul->setText("*");
    button_div->setText("/");
    button_clear->setText("CE");
    button_equal->setText("=");
    button_point->setText(".");
    button_left->setText("(");
    button_right->setText(")");
    button_delete->setText("Del");

    //设置显示窗口

    QTextEdit* text = new QTextEdit(this);
    text->resize(490, 90);
    text->move(10, 10);
    QTextCharFormat fmt;
    fmt.setFont(QFont("Timers", 14, QFont::Bold));
    text->setCurrentCharFormat(fmt);
    text->setEnabled(false);

    //布局
    button_0->resize(90, 90);
    button_0->move(10, 110);

    button_1->resize(90, 90);
    button_1->move(110, 110);

    button_2->resize(90, 90);
    button_2->move(210, 110);

    button_3->resize(90, 90);
    button_3->move(310, 110);

    button_4->resize(90, 90);
    button_4->move(10, 210);

    button_5->resize(90, 90);
    button_5->move(110, 210);

    button_6->resize(90, 90);
    button_6->move(210, 210);

    button_7->resize(90
  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值