📄 caculator.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 + -