有效使用C ++ iomanip库 [英] Effective use of C++ iomanip library

查看:143
本文介绍了有效使用C ++ iomanip库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C ++中创建了一个 Vector 类,它对我的​​问题很有效。我现在清理它,我遇到了下面的代码片段:

I created a Vector class in C++ and it works great for my problems. I am now cleaning it up, and I ran into the following piece of code:

std::ostream& operator<<(std::ostream &output, const Vector &v){
  output<<"["
    <<std::setiosflags(std::ios::right | std::ios::scientific)
    <<std::setw(23)
    <<std::setprecision(16)
    <<v._x<<", "
    <<std::setiosflags(std::ios::right | std::ios::scientific)
    <<std::setw(23)
    <<std::setprecision(16)
    <<v._y<<", "
    <<std::setiosflags(std::ios::right | std::ios::scientific)
    <<std::setw(23)
    <<std::setprecision(16)
    <<v._z<<"]";
  return output;
} 

代码允许打印一个向量 std: :cout<< v<< std :: endl; 。每个数字有23个空格,其中16个是小数。文本是对齐的,以便它将打印:

The code allows to print a vector as std::cout<<v<<std::endl;. Each number has 23 spaces, of which 16 are the decimals. The text is right-aligned so that it will print:

 1.123456123456e+01
-1.123456123456e+01

而不是

1.123456123456e+01
-1.123456123456e+01

重复。如何存储格式(所有 setiosflags setw setprecision 语句),以便你可以说以标准方式打印字符,但是以这种给定格式打印字符。

The code seems awfully repetitive. How can you "store" the format (all the setiosflags, setw and setprecision statements) such that you can say something like "print the characters in a standard way, but the numbers with this given format".

谢谢!

根据Rob Adams的评论,我改变了我的丑陋的代码(正如其他人所指出的那样,会使下一个人的精确度变得更加简洁(正确):

As per Rob Adams' comment, I changed my ugly code (which, as pointed out by others, would mess up the precision for the "next guy") to a more succinct (and correct):

std::ostream& operator<<(std::ostream &output, const Vector &v){
  std::ios_base::fmtflags f = output.flags(std::ios::right | std::ios::scientific);
  std::streamsize p = output.precision(16);
  output<<"["
    <<std::setw(23)<<v._x<<", "
    <<std::setw(23)<<v._y<<", "
    <<std::setw(23)<<v._z
    <<"]";
  output.flags(f);
  output.precision(p);
  return output;
}


推荐答案

> std :: setw()是临时的。其他两个调用, setiosflags setprecision 具有永久效果。

Only std::setw() is temporary. The other two calls, setiosflags, and setprecision have a permanent effect.

因此,您可以将代码更改为:

So, you could change your code to :

std::ostream& operator<<(std::ostream &output, const Vector &v){
  output<<"["
    <<std::setiosflags(std::ios::right | std::ios::scientific)
    <<std::setw(23)
    <<std::setprecision(16)
    <<v._x<<", "
    <<std::setw(23)
    <<v._y<<", "
    <<std::setw(23)
    <<v._z<<"]";
  return output;
} 

但现在你已经为下一个人请改为尝试:

But now you've borked the flags and precision for the next guy. Try this instead:

std::ostream& operator<<(std::ostream &output, const Vector &v){
  std::ios_base::fmtflags f = output.flags(std::ios::right | std::ios::scientific);
  std::streamsize p = output.precision(16);
  output<<"["
    <<std::setw(23)
    <<v._x<<", "
    <<std::setw(23)
    <<v._y<<", "
    <<std::setw(23)
    <<v._z<<"]";
  output.flags(f);
  output.precision(p);
  return output;
} 

最后,如果你绝对必须摆脱常数的重复 23 ,你可以这样做(但我不会推荐):

Finally, if you absolutely have to get rid of the duplication of the constant 23, you could do something like this (but I wouldn't recommend it):

struct width {
  int w;
  width(int w) : w(w) {}
  friend std::ostream& operator<<(std::ostream&os, const width& w) {
    return os << std::setw(width.w);
  }
};


std::ostream& operator<<(std::ostream &output, const Vector &v){
  std::ios_base::fmtflags f = output.flags(std::ios::right | std::ios::scientific);
  std::streamsize p = output.precision(16);
  width w(23);
  output<<"["
    <<w
    <<v._x<<", "
    <<w
    <<v._y<<", "
    <<w
    <<v._z<<"]";
  output.flags(f);
  output.precision(p);
  return output;
} 

另请参见这个问题,他们决定不能使宽度永久。

See also this other question, where they decided that you can't make width permanent.

这篇关于有效使用C ++ iomanip库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆