如何用std :: ostringstream截断整数类型的宽度?

时间:2010-12-15 20:11:50

标签: c++ stl format width ostringstream

说你有类似的东西:

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进行格式化?

2 个答案:

答案 0 :(得分:3)

截断删除有效数字是大多数现代程序员“不赞成的”。在FORTRAN格式化的旧时代,获得像

这样的输出是很常见的
Total Sales
-----------
9,314,832.36
1,700,328.04
*,***,***,**
8,314,159.26
...

即使是现代的Excel也会进入此陷阱,其字段宽度溢出指示为########

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

答案 1 :(得分: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。