⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 caculator.cpp

📁 用VC编写的一个多功能图形界面计算器
💻 CPP
字号:
// Caculator.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "Caculator.h"
#include "CaculatorDlg.h"

char input[200];	// 输入串。
int lookahead;
int pCur;
int yylval;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCaculatorApp

BEGIN_MESSAGE_MAP(CCaculatorApp, CWinApp)
	//{{AFX_MSG_MAP(CCaculatorApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG
	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCaculatorApp construction

CCaculatorApp::CCaculatorApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CCaculatorApp object

CCaculatorApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CCaculatorApp initialization

BOOL CCaculatorApp::InitInstance()
{
	AfxEnableControlContainer();

	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.

#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	Caculator dlg;
	m_pMainWnd = &dlg;
	int nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with OK
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with Cancel
	}

	// Since the dialog has been closed, return FALSE so that we exit the
	//  application, rather than start the application's message pump.
	return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Caculator dialog


Caculator::Caculator(CWnd* pParent /*=NULL*/)
	: CDialog(Caculator::IDD, pParent)
{
	begin=false;
	zeroOk=true;
	//{{AFX_DATA_INIT(Caculator)
	m_Str = _T("");
	//}}AFX_DATA_INIT
}


void Caculator::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(Caculator)
	DDX_Control(pDX, IDC_SHOW, m_Show);
	DDX_Text(pDX, IDC_SHOW, m_Str);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(Caculator, CDialog)
	//{{AFX_MSG_MAP(Caculator)
	ON_BN_CLICKED(IDC_EXIT, OnExit)
	ON_BN_CLICKED(IDC_ONE, OnOne)
	ON_BN_CLICKED(IDC_TWO, OnTwo)
	ON_BN_CLICKED(IDC_THREE, OnThree)
	ON_BN_CLICKED(IDC_FOUR, OnFour)
	ON_BN_CLICKED(IDC_FIVE, OnFive)
	ON_BN_CLICKED(IDC_SIX, OnSix)
	ON_BN_CLICKED(IDC_SEVEN, OnSeven)
	ON_BN_CLICKED(IDC_EIGHT, OnEight)
	ON_BN_CLICKED(IDC_NINE, OnNine)
	ON_BN_CLICKED(IDC_POSNEG, OnPosneg)
	ON_BN_CLICKED(IDC_ZERO, OnZero)
	ON_BN_CLICKED(IDC_DOT, OnDot)
	ON_BN_CLICKED(IDC_ADD, OnAdd)
	ON_BN_CLICKED(IDC_PLUS, OnPlus)
	ON_BN_CLICKED(IDC_MUTIPLY, OnMutiply)
	ON_BN_CLICKED(IDC_DIVID, OnDivid)
	ON_WM_CANCELMODE()
	ON_BN_CLICKED(IDC_RESULT, OnResult)
	ON_BN_CLICKED(IDC_LBRACE, OnLbrace)
	ON_BN_CLICKED(IDC_RBRACE2, OnRbrace)
	ON_BN_CLICKED(IDC_BACK, OnBack)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Caculator message handlers

void Caculator::OnExit() 
{
	// TODO: Add your control notification handler code here
	m_Str="0.";
	UpdateData(false);
	begin=false;
}

void Caculator::OnOne() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("1");
		UpdateData(false);
		begin=true;
	}
	else if(zeroOk){
		UpdateData(true);
		m_Str+="1";
		UpdateData(false);
	}
}

void Caculator::OnTwo() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("2");
		UpdateData(false);
		begin=true;
	}
	else if(zeroOk){
		UpdateData(true);
		m_Str+="2";
		UpdateData(false);
	}
}

void Caculator::OnThree() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("3");
		UpdateData(false);
		begin=true;
	}
	else if(zeroOk){
		UpdateData(true);
		m_Str+="3";
		UpdateData(false);
	}	
}

void Caculator::OnFour() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("4");
		UpdateData(false);
		begin=true;
	}
	else if(zeroOk){
		UpdateData(true);
		m_Str+="4";
		UpdateData(false);
	}	
}

void Caculator::OnFive() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("5");
		UpdateData(false);
		begin=true;
	}
	else if(zeroOk){
		UpdateData(true);
		m_Str+="5";
		UpdateData(false);
	}	
}

void Caculator::OnSix() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("6");
		UpdateData(false);
		begin=true;
	}
	else if(zeroOk){
		UpdateData(true);
		m_Str+="6";
		UpdateData(false);
	}
}

void Caculator::OnSeven() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("7");
		UpdateData(false);
		begin=true;
	}
	else if(zeroOk){
		UpdateData(true);
		m_Str+="7";
		UpdateData(false);
	}	
}

void Caculator::OnEight() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("8");
		UpdateData(false);
		begin=true;
	}
	else if(zeroOk){
		UpdateData(true);
		m_Str+="8";
		UpdateData(false);
	}	
}

void Caculator::OnNine() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("9");
		UpdateData(false);
		begin=true;
	}
	else if(zeroOk){
		UpdateData(true);
		m_Str+="9";
		UpdateData(false);
	}	
}

void Caculator::OnPosneg() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("-");
		UpdateData(false);
		begin=true;
	}
	else{
		UpdateData();
		if(m_Str.GetAt(0)!='-'){
			m_Str.Insert(0,'-');
			UpdateData(false);
		}
		else{
			m_Str.Delete(0);
			UpdateData(false);
		}
	}	
}

void Caculator::OnZero() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T("0");
		UpdateData(false);
		begin=true;
		zeroOk=false;
	}
	else if(zeroOk){
		UpdateData();
		m_Str+="0";
		UpdateData(false);
	}	
}

void Caculator::OnDot() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str=_T(".");
		UpdateData(false);
		begin=true;
	}
	else if(OpIleagel()){
		UpdateData(true);
		m_Str+=".";
		zeroOk=true;
		UpdateData(false);
	}	
}

void Caculator::OnAdd() 
{
	// TODO: Add your control notification handler code here
	if(begin&&OpIleagel()){
		UpdateData(true);
		m_Str+="+";
		UpdateData(false);
	}	
}

void Caculator::OnPlus() 
{
	// TODO: Add your control notification handler code here
	if(begin&&OpIleagel()){
		UpdateData(true);
		m_Str+="-";
		UpdateData(false);
	}	
}

void Caculator::OnMutiply() 
{
	// TODO: Add your control notification handler code here
	if(begin&&OpIleagel()){
		UpdateData(true);
		m_Str+="*";
		UpdateData(false);
	}	
}

void Caculator::OnDivid() 
{
	// TODO: Add your control notification handler code here
	if(begin&&OpIleagel()){
		UpdateData(true);
		m_Str+="/";
		UpdateData(false);
	}	
}

BOOL Caculator::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	if(!begin){
		OnExit();
	}
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void Caculator::OnCancelMode() 
{
	CDialog::OnCancelMode();
	
	// TODO: Add your message handler code here
}

void Caculator::OnResult() 
{
	// TODO: Add your control notification handler code here
	if(begin){
		UpdateData();
		int result=Caculator::Caculate();
		begin=false;
		zeroOk=true;
		m_Str.Format("%d",result);
//		UpdateData(false);
		GetDlgItem(IDC_SHOW)->SetWindowText(m_Str);
		begin=false;
		zeroOk=true;
	}
}

void Caculator::OnRbrace() 
{
	// TODO: Add your control notification handler code here
	if(begin&&RbIleagal()){
		UpdateData();
		m_Str+=")";
		UpdateData(false);
	}
}

void Caculator::OnLbrace() 
{
	// TODO: Add your control notification handler code here
	if(!begin){
		m_Str="(";
		UpdateData(false);
		begin=true;
	}
	else if(LbIleagel()){
		UpdateData();
		m_Str+="(";
		UpdateData(false);
	}
}

void Caculator::OnBack() 
{
	// TODO: Add your control notification handler code here
	if(begin){
		UpdateData();
		if(m_Str.GetLength()>0){
			m_Str.Delete(m_Str.GetLength()-1);
		}
		UpdateData(false);
	}
}

bool Caculator::OpIleagel()
{
	UpdateData();
	char ch=m_Str.GetAt(m_Str.GetLength()-1);
	if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='.'||ch=='('){
		return false;
	}
	return true;
}

bool Caculator::LbIleagel()
{
	UpdateData();
	char ch=m_Str.GetAt(m_Str.GetLength()-1);
	if(ch=='1'||ch=='2'||ch=='3'||ch=='4'||ch=='5'||ch=='6'||ch=='7'||ch=='8'
		||ch=='9'||ch=='0'||ch=='.'||ch==')'){
		return false;
	}
	return true;
}

bool Caculator::RbIleagal()
{
	UpdateData();
	char ch=m_Str.GetAt(m_Str.GetLength()-1);
	if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='.'||ch=='('){
		return false;
	}
	return true;
}


int Caculator::Caculate()
{
	pCur = 0;
	int i=0;
	// 读入输入串
	for(;i<m_Str.GetLength();){
		input[i++]=m_Str.GetAt(i);
	}
	// lookahead 赋初值
	lookahead = yylex();
	return E();
}

int Caculator::yylex()
{
	char num[20];
	int temp = 0;

	// 过滤掉空白
	while ( input[pCur]==' ' ) pCur++;

	// 如果是数字,那么把这个记号的数值计算出来放在 yylval 中
	while (input[pCur] >= '0' && input[pCur] <= '9'){
		num[temp++] = input[pCur++];
	}
	if (temp >0) 
	{
		sscanf(num, "%d", &yylval);
		return NUM;
	}
	
	// 其他记号的处理
	switch (input[pCur++])	// 注意:这里指针往前移了一位
	{
		case '+': return ADD;
		case '*':return MUL;
		case '(':return LBRACE;
		case ')':return RBRACE;
		case '/':return DIV;
		case '-':return SUB;
		case '\0': return END;
		default: return OTHER;
	}
}

int Caculator::E()
{
	switch (lookahead)
	{
		case LBRACE:	// FIRST(TE')={(,num}
		case NUM:
			return T() + E_();
//		case END:		// FOLLOW(E)={),$}
//			return 0;
		default:
//			printf("\n Error\n");
			AfxMessageBox("Error in E().");
			return false;
	}
}

int Caculator::T()
{
	switch (lookahead)
	{
		case LBRACE:	// FIRST(FT')={(,num}
		case NUM:
			return F()*T_();
		default:
//			printf("\n Error\n");
			AfxMessageBox("Error in T().");
			return false;
	}
}

int Caculator::T_()
{
	switch (lookahead)
	{
		case MUL:	// FIRST(*FT')={*}
			Match(MUL);
			return F() * T_();
		case ADD:	// T'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(T')={+,),$}
		case RBRACE:
		case END:
			return 1;
		default:
//			printf("\n Error\n");
			AfxMessageBox("Error in T_().");
			return false;
	}
}

int Caculator::F()
{
	int temp;

	switch(lookahead)
	{
		case LBRACE:	// FIRST((E))={(}
			Match(LBRACE);
			temp = E();
			Match(RBRACE);
			return temp;
		case NUM:		// FIRST(num) = {num}
			temp = yylval;
			Match(NUM);
			return temp;
		default:
//			printf("\n Error\n");
			AfxMessageBox("Error in F().");
			return false;
	}
}

int Caculator::E_()
{
	switch (lookahead)
	{
		case ADD:	// E'-->+TE' 的情况, FIRST(E')={+,e}
			Match(ADD); return T() + E_();

		case RBRACE:// E'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(E')={), $}
		case END:
			return 0;
		default:
//			printf("\n Error\n");
			AfxMessageBox("Error in E_().");
			return false;
	}
}

void Caculator::Match(int t)
{
	if (lookahead == t) lookahead = yylex();
	else 
	{
//		printf("\n Error\n");
		AfxMessageBox("Error in Match().");
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -