将C风格的漂亮打印重构为C ++风格的漂亮打印

时间:2013-02-05 20:52:36

标签: c++ c refactoring string-formatting pretty-print

我想将一些printf / sprintf / fprintf条句重构为ostream / sstream / fstream条款。有问题的代码使用空格填充和固定的小数点数来打印一系列整数和浮点数。

在我看来,这将是Martin Fowler风格的安全,逐步重构的一个很好的候选人,并注意到重要的问题。当然,第一步是将遗留代码放入测试工具中,我已经完成了。

我可以采取哪些缓慢而谨慎的步骤来执行此重构?

2 个答案:

答案 0 :(得分:2)

如果重构本身不是目标,那么你可以通过使用tinyformat之类的格式库来完全避免它(好吧,差不多),它提供类似于printf的接口,但是类型安全且在内部使用IOStreams。

答案 1 :(得分:2)

转换的基本机制:

  • 转换每个printf - 样式的子句%w.pf%w.pe,其中w是字段宽度,p是精度的位数, << setw(w) << setprecision(p) << fixed
  • 将每个printf - 样式条款%wd%wi转换为w,其中<< setw(w)为字段宽度。
  • 在适当的时候将"\n"转换为endl

printf的处理:

  • 以足够的总宽度创建char[](让我们称之为text)。
  • printf(...)转换为sprintf(text, ...),然后使用cout << text实际打印文字。
  • 使用通用说明完成。

fprintf的处理:

  • printf相同,但请使用相应的fstream代替cout
    • 如果您已经有一个打开的C风格FILE对象,此时您不想重构,它会有一点sticky(但是can be done)。
  • 使用通用说明完成。

sprintf的处理:

  • 如果要写入的字符串仅用于输出当前上下文中的流,请参阅上面两个重构之一。
    • 否则,首先创建一个stringstream并将您正在写入的char[]的内容流式传输到该内容中。如果您仍打算从中提取char*,则可以执行std::stringstream::str().c_str()
  • 使用通用说明完成。

常用说明:

  • 将每个子句逐个转换为C ++ - style。
  • 完成后,根据需要删除*printfchar[]声明。
  • 根据需要应用其他重构,特别是“提取方法”(Fowler,重构)。