Jiv*_*son 38 c++ floating-point cout ostream
如何使用std :: cout执行以下操作?
double my_double = 42.0;
char str[12];
printf_s("%11.6lf", my_double); // Prints " 42.000000"
Run Code Online (Sandbox Code Playgroud)
我准备放弃并使用sprintf_s.
更一般地说,我在哪里可以找到std :: ostream格式的引用,它在一个地方列出所有内容,而不是在长篇教程中全部展开?
编辑2017年12月21日 - 请参阅下面的答案.它使用了我在2012年提出这个问题时无法使用的功能.
Kir*_*rov 68
std::cout << std::fixed << std::setw( 11 ) << std::setprecision( 6 ) << my_double;
Run Code Online (Sandbox Code Playgroud)
你需要添加
#include <iomanip>
Run Code Online (Sandbox Code Playgroud)
你需要流操纵器
你可以用你想要的任何字符"填充"空白的地方.像这样:
std::cout << std::fixed << std::setw( 11 ) << std::setprecision( 6 )
<< std::setfill( '0' ) << my_double;
Run Code Online (Sandbox Code Playgroud)
And*_*rey 14
std::cout << boost::format("%11.6f") % my_double;
Run Code Online (Sandbox Code Playgroud)
你必须 #include <boost\format.hpp>
在 C++20 中,你将能够做到
double my_double = 42.0;
char str[12];
std::format_to_n(str, sizeof(str), "{:11.6}", my_double);
Run Code Online (Sandbox Code Playgroud)
或者
std::string s = std::format("{:11.6}", my_double);
Run Code Online (Sandbox Code Playgroud)
同时,您可以使用{fmt} 库,该库提供format_to_n.
免责声明:我是 {fmt} 和 C++20 的作者std::format。
#include <iostream>
#include <iomanip>
int main() {
double my_double = 42.0;
std::cout << std::fixed << std::setw(11)
<< std::setprecision(6) << my_double << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在一般情况下,要避免指定类的东西11,并6在输出点。那是物理标记,而您想要逻辑标记;例如pressure或volume。这样,您可以在一个位置定义压力或体积的格式,并且如果该格式发生更改,则无需搜索整个程序以查找更改格式的位置(也可以不小心更改其他格式)。 。在C ++中,您可以通过定义一个操纵器来做到这一点,该操纵器可以设置各种格式设置选项,最好在完整表达式的末尾还原它们。因此,您最终会编写如下内容:
std::cout << pressure << my_double;
Run Code Online (Sandbox Code Playgroud)
尽管我绝对不会在生产代码中使用它,但我发现以下FFmt格式化程序对快速工作很有用:
class FFmt : public StateSavingManip
{
public:
explicit FFmt(
int width,
int prec = 6,
std::ios::fmtflags additionalFlags
= static_cast<std::ios::fmtflags>(),
char fill = ' ' );
protected:
virtual void setState( std::ios& targetStream ) const;
private:
int myWidth;
int myPrec;
std::ios::fmtflags myFlags;
char myFill;
};
FFmt::FFmt(
int width,
int prec,
std::ios::fmtflags additionalFlags,
char fill )
: myWidth( width )
, myPrec( prec )
, myFlags( additionalFlags )
, myFill( fill )
{
myFlags &= ~ std::ios::floatfield
myFlags |= std::ios::fixed
if ( isdigit( static_cast< unsigned char >( fill ) )
&& (myFlags & std::ios::adjustfield) == 0 ) {
myFlags |= std::ios::internal
}
}
void
FFmt::setState(
std::ios& targetStream ) const
{
targetStream.flags( myFlags )
targetStream.width( myWidth )
targetStream.precision( myPrec )
targetStream.fill( myFill )
}
Run Code Online (Sandbox Code Playgroud)
这样可以编写如下内容:
std::cout << FFmt( 11, 6 ) << my_double;
Run Code Online (Sandbox Code Playgroud)
并作记录:
class StateSavingManip
{
public:
StateSavingManip(
StateSavingManip const& other );
virtual ~StateSavingManip();
void operator()( std::ios& stream ) const;
protected:
StateSavingManip();
private:
virtual void setState( std::ios& stream ) const = 0;
private:
StateSavingManip& operator=( StateSavingManip const& );
private:
mutable std::ios* myStream;
mutable std::ios::fmtflags
mySavedFlags;
mutable int mySavedPrec;
mutable char mySavedFill;
};
inline std::ostream&
operator<<(
std::ostream& out,
StateSavingManip const&
manip )
{
manip( out );
return out;
}
inline std::istream&
operator>>(
std::istream& in,
StateSavingManip const&
manip )
{
manip( in );
return in;
}
Run Code Online (Sandbox Code Playgroud)
StateSavingManip.cc:
namespace {
// We maintain the value returned by ios::xalloc() + 1, and not
// the value itself. The actual value may be zero, and we need
// to be able to distinguish it from the 0 resulting from 0
// initialization. The function getXAlloc() returns this value
// -1, so we add one in the initialization.
int getXAlloc();
int ourXAlloc = getXAlloc() + 1;
int
getXAlloc()
{
if ( ourXAlloc == 0 ) {
ourXAlloc = std::ios::xalloc() + 1;
assert( ourXAlloc != 0 );
}
return ourXAlloc - 1;
}
}
StateSavingManip::StateSavingManip()
: myStream( NULL )
{
}
StateSavingManip::StateSavingManip(
StateSavingManip const&
other )
{
assert( other.myStream == NULL );
}
StateSavingManip::~StateSavingManip()
{
if ( myStream != NULL ) {
myStream->flags( mySavedFlags );
myStream->precision( mySavedPrec );
myStream->fill( mySavedFill );
myStream->pword( getXAlloc() ) = NULL;
}
}
void
StateSavingManip::operator()(
std::ios& stream ) const
{
void*& backptr = stream.pword( getXAlloc() );
if ( backptr == NULL ) {
backptr = const_cast< StateSavingManip* >( this );
myStream = &stream;
mySavedFlags = stream.flags();
mySavedPrec = stream.precision();
mySavedFill = stream.fill();
}
setState( stream );
}
Run Code Online (Sandbox Code Playgroud)