简体   繁体   English

C++11 std::to_string(double) - 没有尾随零

[英]C++11 std::to_string(double) - No trailing zeros

Today I tried out some new functions of the C++11 STL and encountered std::to_string .今天试用了C++11 STL的一些新功能,遇到了std::to_string

Lovely, lovely set of functions.可爱,可爱的一组功能。 Creating a stringstream object for just one double-to-string conversion always seemed overkill to me, so I'm glad we can now do something like this:只为一次双字符串转换创建一个字符串流对象对我来说似乎有点过头了,所以我很高兴我们现在可以做这样的事情:

std::cout << std::to_string(0.33) << std::endl;

The result?结果?

0.330000

I'm not entirely content with that.我对此并不完全满意。 Is there a way to tell std::to_string to leave out the trailing zeros?有没有办法告诉std::to_string省略尾随零? I searched the internet, but as far as I can see the function takes only one argument (the value to be converted).我搜索了互联网,但据我所知,该函数只接受一个参数(要转换的值)。 Back in 'the old days' with stringstreams, you could set the width of the stream, but I'd rather not convert back.回到使用字符串流的“过去”,您可以设置流的宽度,但我宁愿不转换回来。

Anyone encountered this problem before/has a solution?有人遇到过这个问题/有解决方案吗? Some StackOverflow searches yielded nothing.一些 StackOverflow 搜索一无所获。

(A C++11 STL reference: http://en.cppreference.com/w/cpp/string/basic_string/to_string ) (C++11 STL 参考: http ://en.cppreference.com/w/cpp/string/basic_string/to_string)

If all you want to do is remove trailing zeros, well, that's easy.如果您只想删除尾随零,那很容易。

std::string str = std::to_string (f);
str.erase ( str.find_last_not_of('0') + 1, std::string::npos );

The C++11 Standard explicitely says ( 21.5/7 ): C++11 标准明确表示( 21.5/7 ):

Returns: Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of "%d", "%u", "%ld", "%lu", "%lld", "%llu", "%f", "%f", or "%Lf", respectively, where buf designates an internal character buffer of sufficient size返回:每个函数都返回一个字符串对象,该对象保存其参数值的字符表示形式,该参数值将通过使用格式说明符“%d”、“%u”、“%ld”调用 sprintf(buf, fmt, val) 生成"、"%lu"、"%lld"、"%llu"、"%f"、"%f" 或 "%Lf",其中 buf 指定足够大小的内部字符缓冲区

for the functions declared in this order:对于按此顺序声明的函数:

string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);

Thus, you cannot control the formatting of the resulting string.因此,您无法控制结果字符串的格式。

std::to_string gives you no control over the format; std::to_string让您无法控制格式; you get the same result as sprintf with the appropriate format specifier for the type ( "%f" in this case).您会得到与sprintf相同的结果,并使用适当的类型说明符(在本例中为"%f" )。

If you need more flexibility, then you will need a more flexible formatter - such as std::stringstream .如果您需要更大的灵活性,那么您将需要更灵活的格式化程序 - 例如std::stringstream

To leave out the trailing zeros:要省略尾随零:

std::ostringstream oss;
oss << std::setprecision(8) << std::noshowpoint << double_value;
std::string str = oss.str();

Note: #include <sstream> and #include <iomanip>注意: #include <sstream>#include <iomanip>

std::to_string(double) is defined by the standard to just return the same sequence of characters that would be generated by sprintf(buf, "%f", value) . std::to_string(double)由标准定义为仅返回由sprintf(buf, "%f", value)生成的相同字符序列。 No more, no less, especially no way to tweak the format specifier.不多也不少,尤其是无法调整格式说明符。 So no, there is nothing you can do.所以不,你无能为力。

With boost::to_string you cannot control the format either but it will output something closer to what you see in the screen.使用boost::to_string您也无法控制格式,但它会输出更接近您在屏幕上看到的内容。 Same with std::lexical_cast<std::string> .std::lexical_cast<std::string>相同。

For a function-like operation with format control, use str(boost::format("...format...")% 0.33) .对于具有格式控制的类似函数的操作,请使用str(boost::format("...format...")% 0.33)

What's the difference between std::to_string, boost::to_string, and boost::lexical_cast<std::string>? std::to_string、boost::to_string 和 boost::lexical_cast<std::string> 之间有什么区别?

With C++20 we can finally embrace the power of std::format !有了 C++20,我们终于可以拥抱std::format的强大功能了! Let's hope GCC and Clang will catch up to MSVC and implement it soon.让我们希望 GCC 和 Clang 能够赶上 MSVC 并尽快实现它。

std::format("{}\n", 0.33);

A varied solution to the problem since to_string doesn't work.由于to_string不起作用,因此该问题的多种解决方案。 "The Magic Formula" - my CS2400 teacher 《魔方》——我的CS2400老师

std::cout.setf(ios::fixed);
std::cout.setf(ios::showpoint);
std::cout.precision(2);

const double x = 0.33, y = 42.3748;
std::cout << "$" << x << std::endl;
std::cout << "$" << y << std::endl;

Outputs:输出:

$0.33
$42.37

any following output you do with decimal numbers will be set as so.您使用十进制数字执行的任何后续输出都将被设置为这样。

you can always change the setf and precision as you see fit.您可以随时更改您认为合适的 setf 和精度。

Create a custom convert function, remove the tailing zeros if necessary.创建自定义转换函数,如有必要,删除拖尾零。

//! 2018.05.14 13:19:20 CST
#include <string>
#include <sstream>
#include <iostream>
using namespace std;

//! Create a custom convert function, remove the tailing zeros if necessary.  
template<typename T>
std::string tostring(const T &n) {
    std::ostringstream oss;
    oss << n;
    string s =  oss.str();
    int dotpos = s.find_first_of('.');
    if(dotpos!=std::string::npos){
        int ipos = s.size()-1;
        while(s[ipos]=='0' && ipos>dotpos){
            --ipos;
        }
        s.erase ( ipos + 1, std::string::npos );
    }
    return s;
}

int main(){
    std::cout<< tostring(1230)<<endl;
    std::cout<< tostring(12.30)<<endl;
}

The input numbers :输入数字:

1230
12.30

Compile with -std=c++11 , then the result:-std=c++11编译,结果:

1230
12.3

Write a generic helper function, such as below, which you can repurpose for rounding needs within your C++ project.编写一个通用辅助函数,如下所示,您可以将其重新用于 C++ 项目中的舍入需求。

inline static const string roundDouble(const double input, const int decimal_places)
{
    ostringstream str;
    str << fixed << setprecision(decimal_places);
    str << input;
    return str.str();
}
double val
std::wstringstream wss;
wss << val;
cout << wss.str().c_str();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM