浮点数的全局格式化选项
Global formatting options for floating point numbers
我知道不能为基本类型重载(流)操作符,如下所示:
std::ostream & operator<<(std::ostream &stream, const double s) {
stream << std::scientific << std::showpos << std::setprecision(15) << std::to_string(s);
return stream;
}
为基本类型定义全局格式化选项的首选方法是什么?请注意,我希望将格式化应用于任何类型的输出流,而不仅仅是std::cout
这样的特定流。欢迎c++ 11解决方案。有提示吗?
您可以定义自己的操纵符来设置流格式化器。操纵符必须符合<<
操作符所期望的格式:
basic_ostream& operator<<(
std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );
例如:
template <class Char>
basic_ostream<Char>& format_double(basic_ostream<Char>& stream) {
return stream << std::scientific
<< std::showpos
<< std::setprecision(15);
}
然后输入:
cout << format_double << 2.0;
引用
- & lt; & lt;操作员特殊情况(9)
操纵符有两种格式,一种以ios_base
为参数,另一种以basic_ostream
为参数。必须使用后者,因为它没有指定setprecision(int)
的返回值是什么。例如,我的编译器(gcc-4.9)返回一个保存整数的结构体_Setprecision
,并为该结构体和basic_ostream
定义了一个特定的操作符<<
。
重载流是一个坏主意,但是你可以包装它们。如果你想做一个特殊但常见的预处理/后处理,定义一个自定义(模板化)类,它有一个流作为成员(可能在构造函数中受到影响),并在预处理输入和/或之后做一些后处理后将实际的io委托给该流。
class Printer {
ostream &ost;
Printer(ostream& st): ost(st) {
// other initializations ...
}
Printer& operator << (double d) {
ost << std::scientific << std::showpos << std::setprecision(15) << std::to_string(s);
return *this;
}
// others: ostream conversion, other processing...
}
数字类型(整数和浮点数)的格式可以通过确保流使用不同的std::locale
来修改。这个工具可以用来影响在全局std::locale
设置之后创建的所有流的格式化。现有的流也可以通过imbue()
来使用这个修改后的std::locale
。
一个例子可以是这样的:
class special_num_put
: public std::num_put<char> {
virtual iter_type do_put(iter_type it, ios_base& fmt,
char_type fill, double v) const {
fmt.precision(15);
fmt.setf(std::ios_base::showpos);
fmt.setf(std::ios_base::scientific, std::ios_base::floatfield);
return this->std::num_put<char>::do_put(it, fmt, fill, v);
}
// likewise for all of the other numeric types
};
int main() {
std::locale::global(std::locale(std::locale(), new special_num_put));
std::cout.imbue(std::locale()); // deal with existing stream
// likewise for all other preexisting streams
}
请注意,我同意前面的评论,您应该而不是想要做这样的事情。
要扩展fjardon的答案,您可以使用模板为您想要的任何类型创建默认格式,例如
cout << formatted(2.0) << ' ' << formatted(1.4,6) << ' ' << formatted(2.3f)
使用不同的精度等。这可以通过
实现namespace io_formatting {
template<typename Tp>
struct manipulator
{
Tp val;
int prec;
manipulator(Tp x, int p=std::numeric_limits<Tp>::digits10)
: val(x), prec(p) {}
};
template<typename X>
inline std::ostream& operator<<(std::ostream&o, manipulator<X> const&m)
{
return o << std::scientific
<< std::showpos
<< std::setprecision(m.prec)
<< m.val;
}
}
template<typename Tp>
io_formatting::manipulator<Tp> formatted(Tp x) { return {x}; }
template<typename Tp>
io_formatting::manipulator<Tp> formatted(Tp x, int p) { return {x,p}; }
你可以使用专门化和/或SFINAE来区分不同的类型(浮点,整型,复数…)
相关文章:
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- Win32编译器选项和内存分配
- C++格式化输出问题
- C/C++预处理器是否可以检测一些编译器选项
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 通过选项卡的文本设置QTabWidget顺序
- 通过ccmake在cmake中缓存依赖选项
- 格式化浮点值:返回默认值
- 如何传递多个 std::文件系统选项?
- 基于编译器选项的编译二进制路径
- "perf_event_attr"结构的"read_format"属性的选项到底是什么?
- 自动格式化程序> >更改为>>
- 如何从C++中的格式化字符串派生整数?
- 将从格式化文本文件读取的文本数据存储到链表
- 如何应用 libcurl 的持久连接选项
- 在不使用系统的情况下从C++应用程序格式化 Linux 中的 SD 卡
- 从命令行调用Eclipse的格式化选项
- 使用 sscanf 、选项卡格式化日志文件
- 浮点数的全局格式化选项