2014-11-29 7 views
6

Ich brauche etwas Hilfe bei der Ausgabeformatierung mit C++ - Streams. Ich möchte Zahlen mit einem festen Dezimalpunkt und höchstens 2 nachfolgenden Stellen drucken. Ich habe folgendes versucht:Anzahl der abschließenden Nullen für feste Ausgabe begrenzen

#include <iostream> 
#include <iomanip> 
using namespace std; 

int main(int argc, char **argv) 
{ 
    float testme[] = { 0.12345, 1.2345, 12.345, 123.45, 1234.5, 12345 }; 

    std::cout << std::setprecision(2) << std::fixed; 

    for(int i = 0; i < 6; ++i) 
    { 
     std::cout << testme[i] << std::endl; 
    } 

    return 0; 
} 

Die Ausgabe lautet:

0.12 
1.23 
12.35 
123.45 
1234.50 
12345.00 

Aber ich möchte

0.12 
1.23 
12.35 
123.45 
1234.5 
12345 

haben Kann ich dies erreichen, ohne zusätzliche String-Manipulation mit?

Antwort

1

Dies funktioniert (http://ideone.com/CFcVhu), aber es ist nicht so schön ...

#include <iostream> 
#include <iomanip> 
using namespace std; 

int main(int argc, char **argv) 
{ 
    float testme[] = { 0.12345, 1.2345, 12.345, 123.45, 1234.5, 12345 }; 

    //std::cout << std::setprecision(2) << std::fixed; 

    for(int i = 0; i < 6; ++i) 
    { 
     std::cout << ((int)(testme[i]*100.0))/100.0f << std::endl; 
    } 

    return 0; 
} 
2

Ich bin mir nicht bewusst ein suiting Manipulator, daher könnten Sie verwenden:

#include <iostream> 
#include <iomanip> 
#include <cmath> 

template <typename T> 
struct Fixed 
{ 
    const T& value; 
    const unsigned precision; 
    const T significant; 

    Fixed(const T& value, unsigned precision) 
    : value(value), precision(precision), significant(std::pow(10, precision)) 
    {} 

    void write(std::ostream& stream) const { 
     // Adjust stream settings 
     std::ostream::char_type restore_fill = stream.fill('0'); 
     std::ios_base::fmtflags restore_flags = stream.setf(
      std::ios_base::fixed, std::ios_base::floatfield); 
     std::streamsize restore_precision = stream.precision(0); 

     // Split the floating point into an integral and rounded fractional part 
     T integral; 
     unsigned long fractional = std::round(significant * std::modf(value, &integral)); 

     // Determine the length of the fractional part 
     unsigned digits = precision; 
     while(fractional && fractional % 10 == 0) { 
      fractional /= 10; 
      --digits; 
     } 

     // Carry over to the integral part 
     if(! digits && fractional) { 
      integral += 1; 
      fractional = 0; 
     } 

     // Output 
     stream << integral; 
     if(fractional) { 
      stream << '.' << std::setw(digits) << fractional; 
     } 

     // Restore stream settings 
     stream.precision(restore_precision); 
     stream.flags(restore_flags); 
     stream.fill(restore_fill); 
    } 
}; 

template <typename T> 
inline Fixed<T> fixed(const T& value, unsigned precision) { 
    return Fixed<T>(value, precision); 
} 

template <typename T> 
inline std::ostream& operator << (std::ostream& stream, const Fixed<T>& value) { 
    value.write(stream); 
    return stream; 
} 

int main(int argc, char **argv) 
{ 
    float testme[] = { 0.12345, 1.2345, 12.345, 123.45, 1234.5, 12345 }; 
    for(int i = 0; i < 6; ++i) 
    { 
     std::cout << fixed(testme[i], 2) << std::endl; 
    } 

    return 0; 
} 
-1

Mit anderen Worten: , möchten Sie eine Zahl mit 2 Dezimalziffern darstellen, wenn sie kleiner als 1000 ist (immer positiv?), 1 Dezimalzahl, wenn sie kleiner als 10000 ist, und sonst Null. Hmm, wie könnte man das kodifizieren?

Verwandte Themen