73

今天试用了C++11 STL的一些新功能,遇到了std::to_string.

可爱,可爱的一组功能。只为一次双字符串转换创建一个字符串流对象对我来说似乎有点过头了,所以我很高兴我们现在可以做这样的事情:

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

结果?

0.330000

我对此并不完全满意。有没有办法告诉std::to_string省略尾随零?我搜索了互联网,但据我所知,该函数只接受一个参数(要转换的值)。回到使用字符串流的“过去”,您可以设置流的宽度,但我宁愿不转换回来。

有人遇到过这个问题/有解决方案吗?一些 StackOverflow 搜索一无所获。

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

4

9 回答 9

63

如果您只想删除尾随零,那很容易。

std::string str = std::to_string (f);
str.erase ( str.find_last_not_of('0') + 1, std::string::npos );
于 2012-12-04T18:54:37.407 回答
41

C++11 标准明确表示 ( 21.5/7):

返回:每个函数都返回一个字符串对象,该对象保存其参数值的字符表示,该参数值将通过使用格式说明符“%d”、“%u”、“%ld”调用 sprintf(buf, fmt, val) 生成"、"%lu"、"%lld"、"%llu"、"%f"、"%f" 或 "%Lf",其中 buf 指定足够大小的内部字符缓冲区

对于按此顺序声明的函数:

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);

因此,您无法控制结果字符串的格式。

于 2012-12-03T15:55:48.417 回答
16

std::to_string让您无法控制格式;您得到的结果sprintf与使用类型的适当格式说明符相同("%f"在这种情况下)。

如果您需要更大的灵活性,那么您将需要更灵活的格式化程序 - 例如std::stringstream.

于 2012-12-03T15:41:14.493 回答
15

要省略尾随零:

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

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

于 2017-09-26T11:13:51.740 回答
2

std::to_string(double)由标准定义为仅返回由 . 生成的相同字符序列sprintf(buf, "%f", value)。不多也不少,尤其是无法调整格式说明符。所以不,你无能为力。

于 2012-12-03T15:51:17.780 回答
1

boost::to_string您也无法控制格式,但它会输出更接近您在屏幕上看到的内容。与 相同std::lexical_cast<std::string>

对于具有格式控制的类似函数的操作,请使用str(boost::format("...format...")% 0.33).

std::to_string、boost::to_string 和 boost::lexical_cast<std::string> 之间有什么区别?

于 2018-09-12T05:48:04.100 回答
0

创建自定义转换函数,如有必要,删除拖尾零。

//! 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;
}

输入数字:

1230
12.30

编译-std=c++11,然后结果:

1230
12.3
于 2018-05-14T05:18:49.917 回答
0

该问题的多种解决方案to_string不起作用。《魔方》——我的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;

输出:

$0.33
$42.37

您使用十进制数字执行的任何后续输出都将被设置为这样。

您可以随时更改您认为合适的 setf 和精度。

于 2018-04-18T04:27:47.730 回答
0

编写一个通用辅助函数,如下所示,您可以将其重新用于 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();
}
于 2021-08-26T12:48:31.833 回答