MFC 계산기 예제 소스

2006. 9. 23. 12:59

부분부분 올리겠습니다. MFC로 작성되었고, C로 배우는 알고리즘이라는 책에서 거의 모두 옮겨작성되었습니다.


Dlg클래스에서 헤더파일과 CPP파일

class CGuiStackCalcDlg : public CDialog
{
// 생성
public:
CGuiStackCalcDlg(CWnd* pParent = NULL); // 표준 생성자

// 대화 상자 데이터
enum { IDD = IDD_GUISTACKCALC_DIALOG };

protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원


// 구현
protected:
HICON m_hIcon;

// 메시지 맵 함수를 생성했습니다.
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton0();
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton3();
afx_msg void OnBnClickedButton4();
afx_msg void OnBnClickedButton5();
afx_msg void OnBnClickedButton6();
afx_msg void OnBnClickedButton7();
afx_msg void OnBnClickedButton8();
afx_msg void OnBnClickedButton9();
afx_msg void OnBnClickedButtonFirst();
afx_msg void OnBnClickedButtonLast();
afx_msg void OnBnClickedButtonPlus();
afx_msg void OnBnClickedButtonMinus();
afx_msg void OnBnClickedButtonMulti();
afx_msg void OnBnClickedButtonDiv();
afx_msg void OnBnClickedButtonClear();
afx_msg void OnBnClickedButtonResult();
CString m_editResult;
afx_msg void OnBnClickedButtonSigned();
CString m_str;
calculator* calc;
afx_msg void OnBnClickedButtonBack();
};


구현부(CPP파일)
void CGuiStackCalcDlg::OnBnClickedButtonResult()
{
char temp[MAX];
CString buff;
m_str = m_editResult;
calc = new calculator;
calc->postfix(temp, m_str.GetBuffer(0));
if(!calc->is_legal(temp))
{
  AfxMessageBox("Expression is not legal!");
  return;
}
buff.Format("%d", calc->calc(temp));
  m_editResult += "=";
m_editResult += buff;
UpdateData(FALSE);
}


void CGuiStackCalcDlg::OnBnClickedButtonBack()
{
CString buff;
char *temp;
int imsi;

buff = m_editResult;
imsi = strlen(buff.GetBuffer(0));
temp = new char(sizeof(imsi+1));
strcpy(temp, buff.GetBuffer(0));
buff = "";
for(int i=0;i  buff += temp[i];
//하나 감소한 위치까지 다시 복사함으로 back기능수행

m_editResult = buff;
UpdateData(FALSE);
}


calculater클래스에서 각 함수 및 변수

#define MAX 100

class calculator
{
public:
calculator(void);
~calculator(void);
private:
int top;
public:
int push(int t);
int* stack;
int pop(void);
int get_stack_top(void);
int is_stack_empty(void);
int is_operator(int k);
int is_legal(char * s);
int precedence(int op);
void postfix(char* dst, char* src);
int calc(char* p);
};


#include "StdAfx.h"
#include ".\calculator.h"

calculator::calculator(void)
: stack(NULL)
{
top = -1;
stack = new int[MAX];
}

calculator::~calculator(void)
{
delete stack;
}

int calculator::push(int t)
{
if(top >= MAX-1)
{
  AfxMessageBox("Stack overflow");
  return -1;
}
stack[++top] = t;
return 0;
}


int calculator::pop(void)
{
if(top < 0)
{
  AfxMessageBox("Stack Underflow");
  return -1;
}
  return stack[top--];
}

int calculator::get_stack_top(void)
{
return (top < 0)?-1:stack[top];
}

int calculator::is_stack_empty(void)
{
return (top < 0);
}

int calculator::is_operator(int k)
{
return (k=='+' || k == '-' || k == '*' || k == '/');
}

int calculator::is_legal(char * s)
{
int f = 0;
while(*s)
{
  while(*s == ' ')
  s++;
  if(is_operator(*s))
  f--;
  else
  {
  f++;
  while(*s != ' ')
  s++;
  }
  if(f < 1)break;
  s++;
}
return (f == 1);
}

int calculator::precedence(int op)
{
if(op == '(') return 0;
if(op == '+' || op == '-') return 1;
if(op == '*' || op == '/') return 2;
else return 3;
return 0;
}

void calculator::postfix(char* dst, char* src)
{
top = -1;
while(*src)
{
  if(*src == '(')
  {
  push(*src);
  src++;
  }
  else if(*src == ')')
  {
  while(get_stack_top() != '(')
  {
  *dst++ = pop();
  *dst++ = ' ';
  }
  pop();
  src++;
  }
  else if(is_operator(*src))
  {
  while(!is_stack_empty() && precedence(get_stack_top()) >= precedence(*src))
  {
  *dst++ = pop();
  *dst++ = ' ';
  }
  push(*src);
  src++;
  }
  else if(*src >= '0' && *src <= '9')
  {
  do
  {
  *dst++ = *src++;
  } while(*src >= '0' && *src <= '9');
  *dst++ = ' ';
  }
  else
  src++;
}
while(!is_stack_empty())
{
  *dst++ = pop();
  *dst++ = ' ';
}
dst--;
*dst = 0;
}

int calculator::calc(char* p)
{
int i;
top = -1;
while(*p)
{
  if(*p >= '0' && *p <= '9')
  {
  i=0;
  do
  {
  i = i * 10 + *p - '0';
  p++;
  } while(*p >= '0' && *p <= '9');
  push(i);
  }
  else if(*p == '+')
  {
  push(pop() + pop());
  p++;
  }
  else if(*p == '*')
  {
  push(pop() * pop());
  p++;
  }
  else if(*p == '-')
  {
  i = pop();
  push(pop() - i);
  p++;
  }
  else if(*p == '/')
  {
  i = pop();
  push(pop() / i);
  p++;
  }
  else
  p++;
}
return pop();
}

'테크노트 > 기타' 카테고리의 다른 글

객체지향 이야기 #1  (0) 2006.10.06
Grub 삭제하는 방법  (0) 2006.09.28
Standard C++ Library : <ios> Members  (0) 2006.09.23
infix to postfix [소스]  (0) 2006.09.16
infix -> postfix  (0) 2006.09.15

밥짓는아이 테크노트/기타