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を見てきましたが、これを「きれいに」行う方法がないと言える限り、同じ話です...何か提案はありますか?

更新:std :: ostringstreamおよびSTLストリームは、一般に、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 に答える