setw() 是怎么回事?

What's the deal with setw()?

本文关键字:怎么回事 setw      更新时间:2023-10-16

我最近被这样一个事实所困扰,即ios_base::width和/或setw操纵器必须在写入流的每个项目时重置。

也就是说,您必须执行以下操作:

while(whatever)
{
    mystream << std::setw(2) << myval;
}

而不是这个:

mystream.width(2);
while(whatever)
{
    mystream << myval;
}
好的

,好的。

但是有谁知道为什么做出这个设计决定?我是否缺少一些理由,或者这只是标准的黑暗角落?

其他流格式修饰符(如链接的 SO 问题中所述)是"粘性的",而setw则不是。

哪些操纵者应该只影响下一个操作的决定似乎是基于逻辑和经验观察,关于什么倾向于更好地考虑共同的功能需求,因此程序员更容易编写和正确。

以下几点我觉得很相关:

  • some_stream << x应该在大多数时候正常工作
  • 大多数设置宽度的代码将立即或不久后流式传输该值,因此不相关的代码可以假设不会有一些"挂起"宽度值影响其输出
  • 除非有待处理的setw(),否则setfill()无关紧要,因此不会对我们列表顶部的some_stream << x语句产生不利影响
    • 只有当显式设置宽度时,程序员才能/必须根据他们对更大调用上下文的了解来考虑填充字符状态是否合适
  • 一组值使用相同的填充字符是很常见的
  • 其他操纵器(如 hexoct)是持久的,但它们的使用通常在代码块中,该代码块要么弹出先前的状态,要么(讨厌但更容易)将其设置回十进制

由此引出的回答您问题的要点...

  • 如果setw()是抗拒的,则需要在每个流语句之间重置它,以防止不必要的填充......

我的看法是: 如果您希望统一应用,您可以随时执行以下操作。

int width =2;
while(whatever)
{
    mystream << std::setw(width) << myval;
}

但如果它像你提到的那样很粘:

mystream.width(2);
while(whatever)
{
    mystream << myval;
}

如果我想要不同的宽度,每行我必须继续设置宽度。

所以基本上这两种方法几乎是相同的,我喜欢或不喜欢它们取决于我现在在做什么。