我目前正在使用 MFC 和 C++ 实现一个科学计算器。
我已经完成了大部分功能,但我仍在研究括号功能。
在输入框中打字的过程完全没有麻烦。
一旦我输入不带括号的 5+5,我就会得到 10。
但是,当我在括号内输入数字时,该数字将被视为零。例如,我得到 (5)+5= 5。
我花了很多时间思考这个问题,谷歌搜索,并询问 GPT,但我无法得到答案。
如果我错过或做错了什么,请告诉我,谢谢。
我的代码:
void CMFCApplication20Dlg::OnBnClickedButtonLeftParen()
{
CString temp;
GetDlgItem(IDC_STATIC_VIEW)->GetWindowText(temp);
temp += _T("("); // 왼쪽 괄호 추가
SetDlgItemText(IDC_STATIC_VIEW, temp);
m_LeftParenCount++;
}
void CMFCApplication20Dlg::OnBnClickedButtonRightParen()
{
CString temp;
GetDlgItem(IDC_STATIC_VIEW)->GetWindowText(temp);
if (m_LeftParenCount > m_RightParenCount)
{
temp += _T(")"); // 오른쪽 괄호 추가
SetDlgItemText(IDC_STATIC_VIEW, temp);
m_RightParenCount++;
}
else
{
AfxMessageBox(_T("Cannot add right parenthesis. Mismatched parentheses."));
}
}
void CMFCApplication20Dlg::OnBnClickedButtonEquals()
{
CString temp;
GetDlgItem(IDC_STATIC_VIEW)->GetWindowText(temp);
m_LeftParenCount = 0;
m_RightParenCount = 0;
AfterData = _ttof(temp); // 지수값(추가함)
// CString을 double로 변환 (소수점 지원)
double result = 0.0;
double beforeData = _ttof(ViewStrData); // ViewStrData를 CString에서 double로 변환
double afterData = _ttof(temp); // temp를 CString에서 double로 변환
// % 코드임
int percentPos = temp.Find(_T("%"));
if (percentPos != -1)
{
// `%` 기호가 있을 경우, 해당 기호를 기준으로 문자열 분리
CString numberStr = temp.Left(percentPos); // '%' 기호 이전 부분
double number = _ttof(numberStr); // 문자열을 double로 변환
double result = number / 100.0;
// 결과를 문자열로 변환하고 IDC_STATIC_VIEW에 표시
CString resultStr;
resultStr.Format(_T("%.2f"), result);
SetDlgItemText(IDC_STATIC_RESULT, resultStr);
ChangeCheck = true;
Sign = 0;
return;
}
// 계산 로직
switch (Sign)
{
case 1: result = beforeData + afterData; break;
case 2: result = beforeData - afterData; break;
case 3: result = beforeData * afterData; break;
case 4:
if (afterData != 0.0)
result = beforeData / afterData;
else
{
AfxMessageBox(_T("Zero division error!"));
return;
}
break;
case 5:
if (afterData != 0.0)
result = fmod(beforeData, afterData);
else
AfxMessageBox(_T("Zero division error!"));
break;
// 추가적인 연산자 처리...
default: AfxMessageBox(_T("Invalid operation!")); return;
}
// 결과를 결과 창에 표시
UpdateResultView(result);
GetDlgItem(IDC_STATIC_VIEW)->SetWindowText(_T(""));
ChangeCheck = true;
Sign = 0;
}
核心问题是这行代码:
AfterData = _ttof(temp);
_ttof
类函数宏扩展为atof
或_wtof
(取决于_MBCS
和_UNICODE
预处理器符号)。每个函数都记录以执行以下操作:
当传递每个函数都会返回
通过将输入字符解释为数字产生的值。如果输入无法转换为该类型的值,则返回值为 0.0。double
"5"
作为输入时,函数会如实地将其转换为值
5.0
。然而,对于
"(5)"
来说,情况有所不同。虽然人们可以很容易地看出括号是多余的并且不会影响值,但转换函数不会尝试(数学上)解释输入。他们只是继续读取第一个字符 (
'('
),然后出错,因为这不是浮点文字中的有效符号。相反,您必须编写一个能够解释(可能是)中缀表示法的数学表达式的分词器和解析器。
Shunting Yard Algorithm 是一种众所周知的解析问题解决方案。正如评论中指出的那样,有一个 YouTube 视频足够详细地解释了该算法:DIY 编程语言#1:调车场算法。 如果您需要进一步的帮助,我可以编写一个初始实现来帮助您开始。