0

我正在写一个按钮计算器。我将代码分为模型、视图和控制器。该模型对格式一无所知,它只关心数字。所有格式都在视图中完成。该模型将其输入作为按键,每个按键都是枚举的一部分:

typedef enum {

    kButtonUnknown        =   0,
    kButtonMemoryClear    = 100,
    kButtonMemoryPlus     = 112,
    kButtonMemoryMinus    = 109,
    kButtonMemoryRecall   = 114,
    kButtonClear          =  99,
    …
};

当用户按下按钮(比如1)时,模型会收到一个按钮代码(kButtonNum1),将相应的数字添加到字符串输入缓冲区("1")并更新数字输出值(1.0)。然后控制器将数字输出值传递给格式化它的视图(1)。

这一切都很简单,简单和干净,但实际上并不奏效。问题是,当用户输入数字的一部分(例如0.00,要输入0.001)时,输入无法通过模型查看并显示0而不是0.00。我知道为什么会发生这种情况("0.00"::string解析为0::double并格式化为0)。我不知道如何设计计算器,以使代码保持简洁,并且数字将在用户键入时完全显示在屏幕上。

我已经提出了某种解决方案,但这本质上是一种 hack,打破了从计算器模型到显示器的美丽而简单的流程。

想法?


当前解决方案跟踪计算器状态。如果计算器正在构建一个数字,我将计算器输入缓冲区(一个字符串)并直接设置显示内容(也是一个字符串)。否则我会走正确的道路,即。获取数字计算器输出,将其作为 a 传递给视图,double然后视图使用其内部格式化程序为显示创建一个字符串。示例输入:

输入 | 展示 | 模式
------+----------+------------
0 | 0 | 从字符串
0。| 0。| 从字符串
0.0 | 0.0 | 从字符串
0.0+ | 0 | 从号码

这很丑陋。(1) 计算器必须公开其输入缓冲区和状态。(2) 视图必须公开其显示并允许直接使用字符串设置其内容。(3) 我必须复制一些格式化代码来格式化从计算器输入缓冲区得到的字符串。如果用户输入12345.000,我必须显示12,345.000,因此我必须有一个字符串的commification 代码。呸。

4

2 回答 2

1

在我的计算器 (HP48SX) 上,显示中的数字是根据显示数字的设置进行格式化的。现在,如果我输入0.00(或其任何变体),它将显示为0.0000. 也许您可以将显示(即格式化)与内部数字表示分开?就 MVC 而言,我猜这将在 C 中实现为状态。

编辑以回应 OP 的评论。我不完全理解你所谓的按钮计算器的局限性,所以你自己在那里。至于分离,我会这样设计计算器:

  • 模型总是使用你用来表示数字的任何东西:浮点数、双精度数、小数、你有什么。
  • View 始终使用能够很好地呈现数字并允许用户随意输入的字符串。
  • 控制器从字符串转换为数字,从数字转换为字符串。在我最初的建议中,我设想控制器本身将是有状态的(例如存储当前数字格式)并且可以通过按钮进行寻址。但你似乎已经排除了这一点。

如我所见,您的问题是,如果您不将此状态存储在某处,那么您将无法告诉计算器使用除固定*格式以外的任何内容来显示输入的任何数字。固定*我的意思是一种非常有限的灵活性形式,例如始终显示最近输入的数字中的小数位数,而不是绝对固定的,例如 12 位,不多也不少。

于 2010-04-15T15:02:17.657 回答
0

最后我找到了一个更好的解决方案。我已向inputHint格式化程序对象添加了一个属性,该属性负责处理视图中的输出格式。此输入提示接收计算器输入缓冲区的值并影响格式。如果输入提示中有小数点,则强制格式化程序在输出中始终保留小数点,从而解决"0."被格式化为"0". 并且如果输入包含一些小数位数,则格式化程序被迫在输出中保持相同数量的小数位数(解决"0.00"被格式化为的情况"0")。

我仍然必须公开计算器输入缓冲区和状态,但我不必将视图的显示公开为字符串,也不必维护字符串的重复格式化代码路径。

于 2010-04-16T07:24:29.463 回答