You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MFC(C++)科学计算器括号功能异常求助:括号内数值被识别为0

MFC科学计算器括号功能异常问题分析

问题描述

使用MFC和C++开发的科学计算器,多数功能正常,但括号功能存在异常:

  • 无括号时输入5+5,可得到正确结果10
  • 输入带括号的表达式如(5)+5时,括号内的数值会被识别为0,最终计算结果为5

相关代码

左括号按钮点击事件

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("无法添加右括号,括号不匹配。"));
    }
} 

等于按钮点击事件

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("除零错误!"));
                return;
            }
            break;
        case 5: 
            if (afterData != 0.0)
                result = fmod(beforeData, afterData);
            else
                AfxMessageBox(_T("除零错误!"));
            break;
        // 其他运算符处理...
        default: AfxMessageBox(_T("无效操作!")); return;
    } 

    // 在结果窗口显示结果
    UpdateResultView(result);
    GetDlgItem(IDC_STATIC_VIEW)->SetWindowText(_T(""));
    ChangeCheck = true;
    Sign = 0;
} 

问题根源

核心问题在于**_ttof函数无法解析包含括号的表达式**:

  • _ttof的解析逻辑是从字符串起始位置识别数字,遇到非数字字符(如()时立即停止解析
  • 当ViewStrData为"(5)"时,_ttof(ViewStrData)会因第一个字符是(直接返回0,最终导致0 + 5 = 5的错误结果

当前代码的计算逻辑仅支持简单的两数运算,没有处理表达式的语法结构(括号、运算符优先级),直接用字符串转数值的方式无法处理带括号的复杂表达式。

修复方案

要解决括号问题,必须实现完整的表达式解析器,步骤如下:

  1. Token拆分:将输入的表达式字符串拆分为数字、运算符、括号等独立单元
  2. 后缀表达式转换:利用栈结构处理括号和运算符优先级,将中缀表达式(如(5)+5)转换为逆波兰后缀表达式
  3. 后缀表达式计算:遍历后缀表达式,用栈计算最终结果

替换当前代码中直接用_ttof转换字符串的逻辑,改用自定义的表达式解析函数来处理带括号的表达式。

内容的提问来源于stack exchange,提问作者Sanghyeon Woo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 18:15:58