Effective use of C++ iomanip library(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库的有效使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:C++ iomanip库的有效使用
				
        
 
            
        基础教程推荐
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
 - 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
 - 常量变量在标题中不起作用 2021-01-01
 - 在 C++ 中计算滚动/移动平均值 2021-01-01
 - 如何通过C程序打开命令提示符Cmd 2022-12-09
 - 如何检查GTK+3.0中的小部件类型? 2022-11-30
 - 如何在 C++ 中初始化静态常量成员? 2022-01-01
 - 这个宏可以转换成函数吗? 2022-01-01
 - 我有静态或动态 boost 库吗? 2021-01-01
 - C++结构和函数声明。为什么它不能编译? 2022-11-07
 
    	
    	
    	
    	
    	
    	
    	
    	
						
						
						
						
						
				
				
				
				