2

假设你有类似的东西:

std::ostringstream oss;
int value(42);
oss.fill('0');
oss << std::setw(3) << value;
cout << oss.str();

输出:042

这个输出是因为 std::setw 确保了最小宽度,我们告诉流用 0 填充但是你如何做相反的事情并指定最大宽度,以便在 STL 和本机 C++ 中截断显示最好...

目前我有一些我认为是丑陋和低效的黑客:

std::ostringstream oss;
int value(1239999);
oss.fill('0');
oss << std::setw(3) << boost::lexical_cast<std::string, int>(value).substr(0, 3);
cout << oss.str();

输出:123

我看过 boost::format 但据我所知,这是同一个故事,没有办法“漂亮”地做到这一点......有什么建议吗?

更新:与 STL 的其他容器和模板对象相比,通常已知 std::ostringstream 和 STL 流执行缓慢。也许我最好制作一个包装并在内部使用 std::queue 的消息队列对象,然后只使用 sprintf_s 进行格式化?

4

2 回答 2

3

大多数现代程序员“不赞成”截断以删除有效数字。在 FORTRAN 格式化的糟糕日子里,得到像这样的输出是很常见的

Total Sales
-----------
9,314,832.36
1,700,328.04
*,***,***,**
8,314,159.26
...

即使是现代的 Excel 也陷入了这个陷阱,其字段宽度溢出指示为########

如果输出的数字不适合字段宽度,则当前的理念是打破字段宽度的边界并可靠地显示该值。唯一的缺点是如果 FORTRAN 程序要读取输入(因此需要严格的列使用)。

于 2010-12-15T20:20:23.180 回答
0

流格式化功能不打算用作通用字符串操作包。您尝试做的事情在数字上没有多大意义,因此不支持 - 使用子字符串或类似函数是要走的路。您可以(并且应该,如果您在多个地方需要它)编写自己的函数来完成这项工作。

就像是:

#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>

void First3( std::ostream & os, int value ) {
    std::ostringstream oss;
    oss.fill('0');
    oss << std::setw(3) << value;
    os << oss.str().substr( 0, 3 );
}

int main() {
    First3( std::cout, 1239999 );
    std::cout << " ";
    First3( std::cout, 1 );
}

请注意,不需要使用 Boost。

于 2010-12-15T20:16:44.290 回答