【问题标题】:C++ - How to reset the output stream manipulator flags [duplicate]C ++ - 如何重置输出流操纵器标志[重复]
【发布时间】:2010-12-03 13:44:55
【问题描述】:

我有一行代码在我的输出中将填充值设置为“-”字符,但需要将 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

我是不是走错了路?

【问题讨论】:

    标签: c++ manipulators


    【解决方案1】:

    查看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:很好的答案,但不是 great,因为我必须包含 Boost 只是为了保存 iostream 标志。
    • @Isaac:在 C++ 中,在我看来,您要么使用 boost,要么最终重新实现它,或者等待 Boost.Something 被包含在标准中。
    【解决方案2】:

    您可以使用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 守卫中会很好。在日志框架中遇到了这个问题。
    • 这适用于所有系统吗?当我尝试它时,我的 std::cout 拒绝输出任何东西......永远!
    【解决方案3】:

    您可以使用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;
    }
    

    【讨论】:

    • 这是正确的,但你也需要对宽度做同样的事情。
    【解决方案4】:

    您可以手动将 setfill 标志更改为您需要的任何值:

    float number = 4.5;
    cout << setfill('-');
    cout << setw(11) << number << endl; // --------4.5
    cout << setfill(' ');
    cout << setw(11) << number << endl; // 4.5
    

    【讨论】:

    • 将其设置为' ',这可能是也可能不是它在第一个setfill之前的值。
    【解决方案5】:

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

    【讨论】:

    • 原始状态不一定是previous状态。此外,'\0' 声称的功能在哪里记录?我能看到的只是setfill() 只接受char 的语句,没有特殊含义。因此,您将填充字符设置为NUL,这将不会是原来的样子,而且根本不会很有用。还是我遗漏了标准中的某些内容?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 2011-07-17
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多