在 C++ 中转换为字符串时限制浮点数的小数位
Limiting decimal places of a float when converting to string in C++
我正在制作一个打印 std::vector<float>
.
元素的函数
工作代码:
std::vector<float> components { 1, 2, 3 };
string result = "<";
for ( auto it = begin(this->components); it != end(this->components); ++it ) {
result.append(to_string(*it));
if (it != (this->components))
result.append(", ");
}
result.append(">");
std::cout << result;
预期的结果是,如果 "components" 具有元素 1、2、3,例如,它将打印:<1, 2, 3>
。
现在它正在将数字打印为浮点数,当然,就像 < 1.000000, 2.000000, 3.000000, >
。
有没有一种方法可以控制字符串中的小数位数,而不必手动逐个字符地检查它?
附带说明一下,如何防止它在最后一个元素后添加 ','
?
您可以使用 std::stringstream.precision
。
只需创建一个 std::stringstream
将其转换为字符串即可。
像这样:
stringstream ss;
ss.precision(3);
ss << "<";
for ( auto it = begin(this->components); it != end(this->components); ++it ) {
ss << *it;
if (it != (this->components))
ss << ", ";
}
ss << ">";
string result = ss.str();
你可以在投射前使用sprintf()
:
float a = 1.000000;
char aa[20];
sprintf(aa, "%1.3f", a);
这是我 运行:
的完整代码
#include <vector>
#include <iterator>
#include <iostream>
using namespace std;
int main()
{
std::vector<float> components{ 1, 2, 3 };
string result = "<";
for (auto it = components.begin(); it != components.end(); ++it) {
float a = *it;
char aa[20];
sprintf(aa, "%1.3f", a);
result.append(string(aa));
if (it+1 != components.end())
result.append(", ");
}
result.append(">");
std::cout << result.c_str();
getchar();
return 0;
}
输出:
我会使用 stringstream.
这样做
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
int main()
{
std::vector<float> components {1, 2, 3, 1.5f, 2.5f, 3.5f, 1.25f, 2.25f, 3.25f, 1.12345f};
std::stringstream result;
result << "<";
for(auto it = std::begin(components); it != std::end(components); ++it)
{
if(it != std::begin(components))
{
result << ", ";
}
result << *it;
}
result << ">";
std::cout << result.str();
return 0;
}
您还可以使用 std::fixed
和 std::setprecision
根据需要进一步修改输出。
在除第一项之外的所有项目的下一项之前打印逗号修复了尾随逗号问题。
这是一个 demo 的工作原理:
正如@Axalo 已经指出的那样,您可以将 setprecision
与 ostream
一起使用来设置其精度(它可以与任何 ostream
一起使用,而不仅仅是 cout
).
为了消除结尾的逗号,我可能会使用我在别处发布的 infix iterator。
使用它,代码可以写成这样:
#include <iostream>
#include <sstream>
#include <vector>
#include <iomanip>
#include "infix_iterator.h"
int main () {
// Data that would display extra precision if we didn't stop it
std::vector<float> components { 1.123f, 2.234f, 3.345f };
std::ostringstream buff("<", std::ios::app);
buff << std::setprecision(2);
std::copy(components.begin(), components.end(),
infix_ostream_iterator<float>(buff, ", "));
buff << ">";
std::cout << buff.str();
}
结果:<1.1, 2.2, 3.3>
我正在制作一个打印 std::vector<float>
.
工作代码:
std::vector<float> components { 1, 2, 3 };
string result = "<";
for ( auto it = begin(this->components); it != end(this->components); ++it ) {
result.append(to_string(*it));
if (it != (this->components))
result.append(", ");
}
result.append(">");
std::cout << result;
预期的结果是,如果 "components" 具有元素 1、2、3,例如,它将打印:<1, 2, 3>
。
现在它正在将数字打印为浮点数,当然,就像 < 1.000000, 2.000000, 3.000000, >
。
有没有一种方法可以控制字符串中的小数位数,而不必手动逐个字符地检查它?
附带说明一下,如何防止它在最后一个元素后添加 ','
?
您可以使用 std::stringstream.precision
。
只需创建一个 std::stringstream
将其转换为字符串即可。
像这样:
stringstream ss;
ss.precision(3);
ss << "<";
for ( auto it = begin(this->components); it != end(this->components); ++it ) {
ss << *it;
if (it != (this->components))
ss << ", ";
}
ss << ">";
string result = ss.str();
你可以在投射前使用sprintf()
:
float a = 1.000000;
char aa[20];
sprintf(aa, "%1.3f", a);
这是我 运行:
的完整代码#include <vector>
#include <iterator>
#include <iostream>
using namespace std;
int main()
{
std::vector<float> components{ 1, 2, 3 };
string result = "<";
for (auto it = components.begin(); it != components.end(); ++it) {
float a = *it;
char aa[20];
sprintf(aa, "%1.3f", a);
result.append(string(aa));
if (it+1 != components.end())
result.append(", ");
}
result.append(">");
std::cout << result.c_str();
getchar();
return 0;
}
输出:
我会使用 stringstream.
这样做#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
int main()
{
std::vector<float> components {1, 2, 3, 1.5f, 2.5f, 3.5f, 1.25f, 2.25f, 3.25f, 1.12345f};
std::stringstream result;
result << "<";
for(auto it = std::begin(components); it != std::end(components); ++it)
{
if(it != std::begin(components))
{
result << ", ";
}
result << *it;
}
result << ">";
std::cout << result.str();
return 0;
}
您还可以使用 std::fixed
和 std::setprecision
根据需要进一步修改输出。
在除第一项之外的所有项目的下一项之前打印逗号修复了尾随逗号问题。
这是一个 demo 的工作原理:
正如@Axalo 已经指出的那样,您可以将 setprecision
与 ostream
一起使用来设置其精度(它可以与任何 ostream
一起使用,而不仅仅是 cout
).
为了消除结尾的逗号,我可能会使用我在别处发布的 infix iterator。
使用它,代码可以写成这样:
#include <iostream>
#include <sstream>
#include <vector>
#include <iomanip>
#include "infix_iterator.h"
int main () {
// Data that would display extra precision if we didn't stop it
std::vector<float> components { 1.123f, 2.234f, 3.345f };
std::ostringstream buff("<", std::ios::app);
buff << std::setprecision(2);
std::copy(components.begin(), components.end(),
infix_ostream_iterator<float>(buff, ", "));
buff << ">";
std::cout << buff.str();
}
结果:<1.1, 2.2, 3.3>