윈폼을 이용해서 간단한 계산기(DotNetCalc) 만들기
.NET프로그래밍/WinForm 2009. 9. 7. 13:51 |
==> Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace DotNetCalc
{
static class Program
{
/// <summary>
/// 해당 응용 프로그램의 주 진입점입니다.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}
==============================================================================================
==> MainForm.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DotNetCalc
{
public partial class MainForm : Form
{
private string buffer; // 입력된 문자열들을 묶어줄 그릇
public MainForm()
{
InitializeComponent();
}
private void btnCommand_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
#region 각각의 버튼 클릭시 해당 문자열을 buffer에 담기
if (btn == btnOne)
{
buffer += "1";
}
else if (btn == btnTwo)
{
buffer += "2";
}
else if (btn == btnThree)
{
buffer += "3";
}
else if (btn == btnFour)
{
buffer += "4";
}
else if (btn == btnFive)
{
buffer += "5";
}
else if (btn == btnSix)
{
buffer += "6";
}
else if (btn == btnSeven)
{
buffer += "7";
}
else if (btn == btnEight)
{
buffer += "8";
}
else if (btn == btnNine)
{
buffer += "9";
}
else if (btn == btnZero)
{
buffer += "0";
}
else if (btn == btnLeft)
{
buffer += "(";
}
else if (btn == btnRight)
{
buffer += ")";
}
else if (btn == btnPlus)
{
buffer += " + ";
}
else if (btn == btnMinus)
{
buffer += " - ";
}
else if (btn == btnMultiply)
{
buffer += " * ";
}
else if (btn == btnDivide)
{
buffer += " / ";
}
else if (btn == btnPoint)
{
buffer += ".";
}
#endregion
txtExpression.Text = buffer;
}
private void btnClear_Click(object sender, EventArgs e)
{
buffer = String.Empty;
txtExpression.Text = "";
}
private void btnBackspace_Click(object sender, EventArgs e)
{
if (buffer.Length > 0)
{
// 마지막 한자리 삭제
buffer = buffer.Substring(0, buffer.Length - 1);
txtExpression.Text = buffer;
}
}
// 문자열로 지정된 수식을 실제 수식으로 변환 후 결과값 계산
private void btnEnter_Click(object sender, EventArgs e)
{
// 문자열 수식에서 공백 제거
string temp = txtExpression.Text.Replace(" ", "");
if (String.IsNullOrEmpty(temp))
{
MessageBox.Show("수식을 입력하시오.");
return;
}
this.txtExpression.Text += " = \r\n\r\n" + MakeExpression(ref temp).ToString();
buffer = ""; // 버퍼 초기화(= 최상위 buffer는 널값으로 초기화)
}
// MakeExpression : 결과값 텍스트박스에 출력, 공백이 제거되어 넘겨져온 수식을 계산한다.
/// <summary>
/// [4] 문자열로 지정된 계산식을 실제 계산식으로 변경
/// </summary>
/// <param name="str">3 * (2 + 3)</param>
/// <returns>15</returns>
public double MakeExpression(ref string str)
{
int index = 0; // 문자 위치
// 구문 결과값 가져오기
double value = Sentence(ref str, ref index);
while (index < str.Length)
{
switch (str[index])
{
case '+':
++(index);
value += Sentence(ref str, ref index);
break;
case '-':
++(index);
value -= Sentence(ref str, ref index);
break;
default: // 엉뚱한 값이 들어오는 경우
MessageBox.Show("잘못된 구문입니다.");
break;
}
}
return value;
}
/// <summary>
/// [3] 하나의 완성된 수식을 계산하는 메서드
/// (3 * 5) = 15
/// </summary>
/// <param name="str">(3 * 5)</param>
/// <param name="index">0</param>
/// <returns>15</returns>
public double Sentence(ref string str, ref int index)
{
double value = GetNumber(ref str, ref index); // 첫번째 숫자
while (index < str.Length)
{
if (str[index] == '*')
{
++(index);
value *= GetNumber(ref str, ref index);
}
else if (str[index] == '/')
{
++(index);
value /= GetNumber(ref str, ref index);
}
else
break;
}
return value;
}
/// <summary>
/// [2] 문자열에서 첫번째 나오는 숫자형을 실제 숫자형으로 변환시켜주는 함수
/// </summary>
/// <param name="str">(12.34+3)</param>
/// <param name="index">1</param>
/// <returns>12.34(숫자형)</returns>
public double GetNumber(ref string str, ref int index)
{
double value = 0.0;
// GetSubstring함수 호출해서 괄호안에 있는 문자열만 가져오기
if (str[index] == '(')
{
++(index);
string substr = GetSubstring(ref str, ref index);
return MakeExpression(ref substr); // 괄호안의 수식만 먼저 계산
}
while ((index < str.Length) && Char.IsDigit(str, index))
{
value = 10.0 * value + Char.GetNumericValue(str[(index)]);
++(index);
}
if ((index == str.Length) || str[index] != '.') return value;
double factor = 1.0;
++(index);
while ((index < str.Length) && Char.IsDigit(str, index))
{
factor *= 0.1;
value = value + Char.GetNumericValue(str[index]) * factor;
++(index);
}
return value;
}
//[1] 괄호안에 있는 하위 문자열을 추출(하는 함수 만들기) : (123+5) => 123+5만 추출
public string GetSubstring(ref string str, ref int index) // GetSubstring : 괄호안의 문자열을 추출하는 함수
{
string substr = ""; // 하위 문자열 저장
int numL = 0; // 왼쪽 괄호의 개수
int bufindex = index; // 인덱스의 시작 값
while (index < str.Length)
{
switch (str[index])
{
case ')' :
if (numL == 0)
{
char[] substrChars = new char[index - bufindex];
str.CopyTo(bufindex, substrChars, 0, substrChars.Length);
substr = new String(substrChars);
++(index);
return substr;
}
else
numL--; // 왼쪽 괄호와 일치하는 오른쪽 괄호가 나타날 시 감소
break;
case '(' :
numL++;
break;
}
++(index);
}
MessageBox.Show("잘못된 구문입니다.");
return substr;
}
}
}
< 실행결과 >
'.NET프로그래밍 > WinForm' 카테고리의 다른 글
"주소록" 프로젝트에 아이콘(Icon)이미지 만들어서 "주소록 바로가기" 아이콘에 넣기 및 "주소록 Setup파일" 생성하기 (0) | 2009.09.08 |
---|---|
DotNetCalc(간단한 계산기 프로그램) Setup파일 생성하기 (0) | 2009.09.08 |
131. WinForm을 이용하여 주소록 만들기(데이터 처리는 파일처리를 기반으로 함) (0) | 2009.09.03 |
129. 폼 클로징(즈) 이벤트 (FormClosing) (0) | 2009.09.02 |
128. CurveList (다른 폼(ex : 메모장)에 의해 의해 내가 마우스로 폼에 그렸던 그림 손상시키지 않기.) (0) | 2009.09.02 |