【问题标题】:Formatting output in C++在 C++ 中格式化输出
【发布时间】:2021-08-17 22:03:52
【问题描述】:

在 C++ 代码中,我打印了一个双变量矩阵。但是,因为它们都有不同的位数,所以输出格式被破坏了。一种解决方案是 cout.precision(5) 但我希望不同的列具有不同的精度。此外,由于在某些情况下存在负值,- 符号的存在也会导致问题。如何解决这个问题并生成格式正确的输出?

【问题讨论】:

    标签: c++ output-formatting


    【解决方案1】:

    在我的脑海中,你可以使用 setw(int) 来指定输出的宽度。

    像这样:

    std::cout << std::setw(5) << 0.2 << std::setw(10) << 123456 << std::endl;
    std::cout << std::setw(5) << 0.12 << std::setw(10) << 123456789 << std::endl;
    

    给出这个:

        0.2    123456
       0.12 123456789
    

    【讨论】:

    • 仅供参考:在执行 std::setw(x) 时,请确保 x 大于您的小数精度。
    • 这是正确的答案,但如果没有额外的库,它在 Ubuntu (gcc) 上不起作用:#include &lt;iomanip&gt;。在这里查看:stackoverflow.com/a/18983787/4960953
    【解决方案2】:

    正如其他人所说,关键是使用操纵器。他们什么 忽略说的是您通常使用您编写的操纵器 你自己。一个FFmt 操纵器(对应于F 格式 Fortran 相当简单:

    class FFmt
    {
        int myWidth;
        int myPrecision;
    public:
        FFmt( int width, int precision )
            : myWidth( width )
            , myPrecision( precision )
        {
        }
    
        friend std::ostream& 
        operator<<( std::ostream& dest, FFmt const& fmt )
        {
            dest.setf( std::ios_base::fixed, std::ios_base::formatfield );
            dest.precision( myPrecision );
            dest.width( myWidth );
            return dest;
        }
    };
    

    这样,你可以为每一列定义一个变量,比如:

    FFmt col1( 8, 2 );
    FFmt col2( 6, 3 );
    //  ...
    

    然后写:

    std::cout  << col1 << value1
        << ' ' << col2 << value2...
    

    一般来说,除了在最简单的程序中,您可能不应该 使用标准操纵器,而是基于自定义操纵器 你的申请;例如temperaturepressure 如果是这样的话 你处理的事情。这样,在代码中就很清楚了 您正在格式化,如果客户突然要求再输入一位数字 压力,你知道在哪里做出改变。

    【讨论】:

    • 记住你需要包含 让它找到 setw()
    • @user1603472 是的,但我的代码没有使用std::setw
    • 对不起,我的错,我点击了错误的地方,是一个快速评论放入
    【解决方案3】:

    使用manipulators

    来自样本here

    #include <iostream>
    #include <iomanip>
    #include <locale>
    int main()
    {
        std::cout.imbue(std::locale("en_US.utf8"));
        std::cout << "Left fill:\n" << std::left << std::setfill('*')
                  << std::setw(12) << -1.23  << '\n'
                  << std::setw(12) << std::hex << std::showbase << 42 << '\n'
                  << std::setw(12) << std::put_money(123, true) << "\n\n";
    
        std::cout << "Internal fill:\n" << std::internal
                  << std::setw(12) << -1.23  << '\n'
                  << std::setw(12) << 42 << '\n'
                  << std::setw(12) << std::put_money(123, true) << "\n\n";
    
        std::cout << "Right fill:\n" << std::right
                  << std::setw(12) << -1.23  << '\n'
                  << std::setw(12) << 42 << '\n'
                  << std::setw(12) << std::put_money(123, true) << '\n';
    }
    

    输出:

    Left fill:
    -1.23*******
    0x2a********
    USD *1.23***
    
    Internal fill:
    -*******1.23
    0x********2a
    USD ****1.23
    
    Right fill:
    *******-1.23
    ********0x2a
    ***USD *1.23
    

    【讨论】:

      【解决方案4】:

      查看流manipulators,尤其是std::setwstd::setfill

      float f = 3.1415926535;
      std::cout << std::setprecision(5)   // precision of floating point output
                << std::setfill(' ')      // character used to fill the column
                << std::setw(20)          // width of column
                << f << '\n';             // your number
      

      【讨论】:

        【解决方案5】:

        尝试使用 setw 操纵器。更多信息请参考http://www.cplusplus.com/reference/iostream/manipulators/setw/

        【讨论】:

          【解决方案6】:

          有一种使用 i/o 操纵器的方法,但我觉得它很笨拙。我只想写一个这样的函数:

          template<typename T>
          std::string RightAligned(int size, const T & val)
          {
              std::string x = boost::lexical_cast<std::string>(val);
              if (x.size() < size)
                  x = std::string(size - x.size(), ' ') + x;
              return x;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-02-10
            • 1970-01-01
            • 1970-01-01
            • 2010-11-28
            • 1970-01-01
            相关资源
            最近更新 更多