반응형
WinForm에 익숙해지기 위해 기본적인 사칙연산을 수행하는 계산기 프로그램을 만들어 봤다
구현사항
- 버튼의 이벤트 처리
- 계산 로직
- 결과 표시
- 오류 처리
- 소수점 계산등의 추가기능
나누기 버튼 예시
- 사칙연산 버튼 클릭 시 어떤 계산을 수행할지 currentOperator 변수에 Operator Enum을 설정하고(Add, Sub, Mul, Div 중 하나), 계산과정 창에 수행할 계산 기호 추가함
public partial class Form1 : Form
{
enum Operators
{
None,
Add,
Sub,
Mul,
Div,
Res
}
Operators currentOperator = Operators.None;
}
private void ButtonDivide_Click(object sender, EventArgs e)
{
try
{
if (currentOperator != Operators.None && isNumClicked)
{
display_process.Text = "";
CalCulOperator(currentOperator);
isNumClicked = false;
}
firstOper = double.Parse(display.Text);
currentOperator = Operators.Div;
operatorChangeFlag = true;
if (display_process.Text.Contains("="))
{
display_process.Text = "";
}
if (display_process.Text.Contains("÷") == false)
{
display_process.Text = "";
display_process.Text += display.Text + " ÷ ";
}
}
catch (Exception ex)
{
LogException(ex);
}
}
숫자버튼 예시
- 숫저버튼이 눌릴경우, operatorChangeFlag를 통해 이전 이벤트가 사칙연산인지 확인, 사칙연산이라면 결과차으이 숫자를 지우고 새로운 숫자를 입력함
private void ButtonOne_Click(object sender, EventArgs e)
{
try
{
Cal_Res_Reset();
if (operatorChangeFlag == true)
{
display.Text = "";
operatorChangeFlag = false;
}
string strNumber = display.Text += "1";
isNumClicked = true;
display.Text = Change_Numtype(strNumber);
}
catch (Exception ex)
{
LogException(ex);
}
}
계산기능예시
- Enum 정의를 통해 연산과정의 가독성을 높였으며 설정된 연산에 따라 firstOper에 저장된 변수와 현재 결과창에 있는 숫자를 secondOper에 저장 후 계산을 수행 및 결과를 송출
- 이부분은 C# 스타일상 switch case로 구현했으면 깔끔한 코드가 될 수 있었던거 같다
private void CalCulOperator(Operators currentOperator)
{
secondOper = double.Parse(display.Text);
if (currentOperator == Operators.Add)
{
firstOper += secondOper;
display.Text = firstOper.ToString();
}
else if (currentOperator == Operators.Sub)
{
firstOper -= secondOper;
display.Text = firstOper.ToString();
}
else if (currentOperator == Operators.Mul)
{
firstOper *= secondOper;
display.Text = firstOper.ToString();
}
else if (currentOperator == Operators.Div)
{
if (secondOper == 0)
{
display.Text = "0으로 나눌 수 없습니다";
}
else
{
firstOper /= secondOper;
display.Text = firstOper.ToString();
}
}
오류처리
- 각 기능별 예기치 못한 오류 발생 시, 오류를 확인하라는 메시지 박스로 안내 후, log 기록 및 저장
- 각 기능을 try ~ catch를 통해서 오류 발생 시, 해당코드가 실행되도록 구성시간, 예외타입, 메시지, StackTrace 등을 통해 코드 상 어디부분에 에러가 발생하였는지 확인 로그로 가능
public void LogException(Exception ex)
{
string logFileName = $"error_{DateTime.Now:yyyyMMdd}.log";
string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, logFileName);
try
{
if (!File.Exists(logFilePath))
{
using (StreamWriter newFileWriter = new StreamWriter(logFilePath, false))
{
newFileWriter.WriteLine($"[Error Log - {DateTime.Now}]");
}
}
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
writer.WriteLine($"Exception Type: {ex.GetType().Name}");
writer.WriteLine($"Message: {ex.Message}");
writer.WriteLine($"StackTrace: {ex.StackTrace}");
writer.WriteLine(new string('-', 50));
}
display.Text = $"Exception Error! {ex.Message}";
}
catch (Exception logEx)
{
display.Text = $"Exception Log record Error! {logEx.Message}";
}
}