문제

Say you have something like:

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

OUTPUT: 042

This output is because std::setw ensures a minimum width and we told the stream to fill with 0 however how do you do the opposite and specify a maximum width so that display will be truncated in STL and native C++ preferably ...

Currently I have something which I consider an ugly and inefficient hack:

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();

OUTPUT: 123

I've looked at boost::format but it's the same story there as far as I can tell there is no way to do this "prettily" ... any suggestions?

UPDATE: std::ostringstream and STL streams in general are known to perform slowly compared to other containers and template objects of STL. Perhaps I would be better off making a message queue object which wraps and internally uses a std::queue and then just use sprintf_s for formatting purposes?

도움이 되었습니까?

해결책

The stream formatting capabilities are not intended as a general purpose string manipulation package. What you are trying to do does not make much sense numerically, so it is not supported - using the substring or similar functions is the way to go. You can (and should, if you need this in more than one place) write your own function to do the job.

Something like:

#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 );
}

Note there is no need for Boost to be used.

다른 팁

Truncating to remove significant digits is "frowned upon" by most modern programmers. In the bad old days of FORTRAN formatting, it was pretty common to get output like

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

Even modern day Excel falls into this trap with its field width overflow indication of ########

If the number being output does not fit into the field width, the current philosophy is to break the boundaries of the field width and reliably show the value. The only disadvantage would be if a FORTRAN program is going to read the input (thus expecting strict column usage).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top