C++ - 如何重置输出流操作符标志位

27

我有一行代码,它将输出的填充值设为“-”字符,但需要将setfill标志重置为其默认的空格字符。我该怎么做?

cout << setw(14) << "  CHARGE/ROOM" << endl;
cout << setfill('-') << setw(11) << '-' << "  " << setw(15) << '-' << "   " << setw(11) << '-' << endl;

我认为这可能有效:

cout.unsetf(ios::manipulatorname) // Howerver I dont see a manipulator called setfill

我走错了路吗?

5个回答

33
你可以使用copyfmt来保存cout的初始格式。完成格式化输出后,您可以再次使用它来恢复默认设置(包括填充字符)。
{
    // save default formatting
    ios init(NULL);
    init.copyfmt(cout);

    // change formatting...
    cout << setfill('-') << setw(11) << '-' << "  ";
    cout << setw(15) << '-' << "   ";
    cout << setw(11) << '-' << endl;

    // restore default formatting
    cout.copyfmt(init);
}

很惊讶之前没有人发布这个 :) 但是将其转换为RAII守卫可能会更好,以防抛出异常。在日志框架中遇到过这个问题。 - M.M
这在所有系统上都能工作吗?当我尝试时,我的std::cout拒绝输出任何东西...永远! - BitTickler
这太棒了!它也适用于std::hex。 - kingsjester
这里有一个简单的RAII实现:https://github.com/gelldur/gcpp/blob/master/src/gcpp/stream/StreamScopeFormat.hpp - Gelldur

31

可以查看Boost.IO_State_Savers,它提供了 iostream 标志的 RAII 风格作用域保护。

示例:

#include <boost/io/ios_state.hpp>

{
  boost::io::ios_all_saver guard(cout); // Saves current flags and format

  cout << setw(14) << "  CHARGE/ROOM" << endl;
  cout << setfill('-') << setw(11) << '-' << "  " << setw(15) << '-' << "   " << setw(11) << '-' << endl;
// dtor of guard here restores flags and formats
}

本库还提供了更专业的保护机制(仅限于填充、宽度、精度等)。有关详细信息,请参见文档。


很棒的答案,应该被采纳。 - gd1
22
@gd1 的回答不错,但并不是“很好”,因为我必须包含 Boost 才能保存 iostream 标志。 - Isaac
3
在C++中,我觉得你要么使用boost,要么不断重新实现它,或者等待Boost.Something被纳入标准。 - gd1

10
你可以使用ios::fill()函数来设置和恢复填充字符。 http://www.cplusplus.com/reference/iostream/ios/fill/
#include <iostream>
using namespace std;

int main () {
  char prev;

  cout.width (10);
  cout << 40 << endl;

  prev = cout.fill ('x');
  cout.width (10);
  cout << 40 << endl;

  cout.fill(prev);

  return 0;
}

这是正确的,但你需要对宽度也执行相同的操作。 - Jan Hudec

3
您可以手动更改setfill标志,使其符合您的需求:
float number = 4.5;
cout << setfill('-');
cout << setw(11) << number << endl; // --------4.5
cout << setfill(' ');
cout << setw(11) << number << endl; // 4.5

4
这将它设置为 ' ',这可能是第一次 setfill 前的值,也可能不是。 - Keith Thompson

-2

空字符将其重置为原始状态: setfill('\0')


2
原始状态不一定是先前状态。此外,'\0'的这个声明函数在哪里记录?我所看到的只有setfill()接受一个char的说明,没有特殊的含义。因此,您将设置填充字符为NUL,这不会是它最初的样子,也不会非常有用。或者我错过了标准中使其工作的内容吗? - underscore_d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接