8

我的代码:

std::vector<double> thePoint(4);
thePoint[0] = 86;
thePoint[1] = -334.8836574; 
thePoint[2] = 24.283;
thePoint[3] = 345.67675;

ofstream file1(tempFileName, ios::trunc);
file1 << std::setprecision(16)              << thePoint[0] << " ";
file1 << std::fixed << std::setprecision(2) << thePoint[1] << " ";
file1 << std::setprecision(16)              << thePoint[2] << " ";
file1 << std::setprecision(16)              << thePoint[3];

我得到:

86 -334.88 24.28300000000000 345.6767500000000

我想:

86 -334.88 24.283 345.67675

与其他挑剔代码的接口需要奇怪的格式。

4

2 回答 2

11

你应该做这个:

file1 << std::fixed << std::setprecision(2) << thePoint[1] << " ";
file1.unsetf(ios_base::fixed);
file1 << std::setprecision(16)              << thePoint[2];

floatfield格式标志可以采用它的两个可能值中的任何一个(使用操纵器和fixedscientific,或者不采用它们(使用ios_base::unsetf)。

于 2012-08-23T15:20:16.850 回答
6

您可以通过将 floatfield 强制为空值来做到这一点:

file1.setf( std::ios_base::fmtflags(), std::floatfield );

然而,在实践中,很少有人愿意这样做。通常的协议是保存格式标志,并在您完成时恢复它们:

std::ios_base::fmtflags originalFlags = file1.flags();
//  ...
file1.flags( originalFlags );

当然,您通常会在实际程序中使用 RAII 来执行此操作。您的工具箱中应该有一个IOSave类,它将在其构造函数中保存标志、精度和填充字符,并在析构函数中恢复它们。

std::setprection直接使用等也不是很好的做法。更好的解决方案是定义您自己的操纵器,名称如pressionor volume,并使用它们。这是一种逻辑标记,意味着您可以从一个中心位置控制例如印刷的格式,而不是让它遍布整个程序。如果您编写自己的操纵器,让它们在完整表达式的末尾恢复原始格式参数相对容易。(操纵器对象将是临时对象,在完整表达式结束时被破坏。)

于 2012-08-23T16:32:37.200 回答