Esc*_*alo 7 c++ iostream stream iomanip
我Vector用C++ 创建了一个类,它对我的问题非常有用.我现在正在清理它,我遇到了以下代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
该代码允许将矢量打印为std::cout<<v<<std::endl;.每个数字有23个空格,其中16个是小数.文本右对齐,以便打印:
1.123456123456e+01
-1.123456123456e+01
Run Code Online (Sandbox Code Playgroud)
代替
1.123456123456e+01
-1.123456123456e+01
Run Code Online (Sandbox Code Playgroud)
代码似乎非常重复.你怎么能"存储"的格式(所有的setiosflags,setw和setprecision语句),这样你就会这样说:"这个给定的格式打印以标准方式中的字符,但数字".
谢谢!
编辑
根据Rob Adams的评论,我改变了我的丑陋代码(正如其他人所指出的那样,会让"下一个人"的精确度变得更加简洁(和正确)):
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;
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*obᵩ 10
只是std::setw()暂时的.另外两个电话,setiosflags并且setprecision具有永久效果.
因此,您可以将代码更改为:
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;
}
Run Code Online (Sandbox Code Playgroud)
但是现在你已经为下一个人提供了标志和精确度.试试这个:
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;
}
Run Code Online (Sandbox Code Playgroud)
最后,如果你必须摆脱常量的重复23,你可以做这样的事情(但我不推荐它):
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;
}
Run Code Online (Sandbox Code Playgroud)
另见这个问题,他们决定你不能使宽度永久.