Formating of floats using iostream

Discussion in 'C++' started by eriwik@student.chalmers.se, Nov 17, 2006.

  1. Guest

    I'm trying to write floats to a file following a specific format (8
    characters/record, and some other rules) and seem to have solved all
    but one problem. There is no way of telling the maximum characters to
    output. For positive numbers this is no problem since I can specify the
    precision (number of digits not counting the decimal-point), however
    when the number is negative the minus-sign does not count towars the
    precision (which it shouldn't really), which has the effect that a
    value that is written as 8 characters when positive is 9 when negative.
    The following illustrates the problem:

    #include <iostream>
    #include <ios>

    int main()
    {
    std::cout.precision(7);
    std::cout.setf(std::ios_base::showpoint);

    std::cout << 54.325617 << " ";
    std::cout << -54.325617 << " ";
    std::cout << 45.545 << " ";
    float f = 3434;
    std::cout << f << " ";

    return 0;
    }

    This outputs "54.32562 -54.32562 45.54500 3434.000".

    All but the second number is 8 characters long, does anyone have a
    solution to this or will I have to make a test before writing each
    number and see if it's negative, and then reduce precision to 6?

    --
    Erik Wikström
     
    , Nov 17, 2006
    #1
    1. Advertising

  2. mlimber Guest

    wrote:
    > I'm trying to write floats to a file following a specific format (8
    > characters/record, and some other rules) and seem to have solved all
    > but one problem. There is no way of telling the maximum characters to
    > output. For positive numbers this is no problem since I can specify the
    > precision (number of digits not counting the decimal-point), however
    > when the number is negative the minus-sign does not count towars the
    > precision (which it shouldn't really), which has the effect that a
    > value that is written as 8 characters when positive is 9 when negative.
    > The following illustrates the problem:
    >
    > #include <iostream>
    > #include <ios>
    >
    > int main()
    > {
    > std::cout.precision(7);
    > std::cout.setf(std::ios_base::showpoint);
    >
    > std::cout << 54.325617 << " ";
    > std::cout << -54.325617 << " ";
    > std::cout << 45.545 << " ";
    > float f = 3434;
    > std::cout << f << " ";
    >
    > return 0;
    > }
    >
    > This outputs "54.32562 -54.32562 45.54500 3434.000".
    >
    > All but the second number is 8 characters long, does anyone have a
    > solution to this or will I have to make a test before writing each
    > number and see if it's negative, and then reduce precision to 6?


    Use std::setw in <iomanip>.

    Cheers! --M
     
    mlimber, Nov 17, 2006
    #2
    1. Advertising

  3. Guest

    On 17 Nov, 14:01, "mlimber" <> wrote:
    > wrote:

    [snip]
    > > All but the second number is 8 characters long, does anyone have a
    > > solution to this or will I have to make a test before writing each
    > > number and see if it's negative, and then reduce precision to 6?

    >
    >Use std::setw in <iomanip>.


    Yeah, so I thought at first, but according to the standard that's the
    same as doing std::cout.width(8), which in turn sets the _minimul_
    field width, not max. So it basically just tells the stream how many
    fill-characters to put in if the field is too small :-(

    --
    Erik Wikström
     
    , Nov 17, 2006
    #3
  4. mlimber Guest

    wrote:
    > On 17 Nov, 14:01, "mlimber" <> wrote:
    > > wrote:

    > [snip]
    > > > All but the second number is 8 characters long, does anyone have a
    > > > solution to this or will I have to make a test before writing each
    > > > number and see if it's negative, and then reduce precision to 6?

    > >
    > >Use std::setw in <iomanip>.

    >
    > Yeah, so I thought at first, but according to the standard that's the
    > same as doing std::cout.width(8), which in turn sets the _minimul_
    > field width, not max. So it basically just tells the stream how many
    > fill-characters to put in if the field is too small :-(


    If you must maintain the 8 character width, drop the precision by 1,
    either universally or only on negative numbers:

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

    class HardWidth
    {
    public:
    HardWidth( const double f, const unsigned width=8 )
    {
    const unsigned prec = ( f < 0 ? width - 2 : width - 1 );
    m_oss << showpoint << setw( width-1 ) << setprecision( prec ) << f;
    }

    friend inline std::eek:stream& operator<<( std::eek:stream &os, const
    HardWidth &h )
    {
    return os << h.m_oss.str();
    }

    private:
    ostringstream m_oss;
    };

    int main()
    {
    cout << HardWidth( 12.3456789 ) << " ";
    cout << HardWidth( -12.3456789 ) << " ";
    return 0;
    }

    // Output: 12.34568 -12.3457

    You could also turn on the plus sign by using std::showpos.

    Cheers! --M
     
    mlimber, Nov 17, 2006
    #4
  5. red floyd Guest

    mlimber wrote:
    > wrote:
    >> On 17 Nov, 14:01, "mlimber" <> wrote:
    >>> wrote:

    >> [snip]
    >>>> All but the second number is 8 characters long, does anyone have a
    >>>> solution to this or will I have to make a test before writing each
    >>>> number and see if it's negative, and then reduce precision to 6?
    >>> Use std::setw in <iomanip>.

    >> Yeah, so I thought at first, but according to the standard that's the
    >> same as doing std::cout.width(8), which in turn sets the _minimul_
    >> field width, not max. So it basically just tells the stream how many
    >> fill-characters to put in if the field is too small :-(

    >
    > If you must maintain the 8 character width, drop the precision by 1,
    > either universally or only on negative numbers:
    >

    Then I'd argue that's a flaw in iostream formatting. In printf (yes, I
    know it's not typesafe), you can specify %X.Ylf format. The amount of
    hoop-jumping needed for setting widths and formatting in iostreams is
    excessive.

    Mind you, I *LIKE* iostreams. They're very useful, and much cleaner
    than printf .... EXCEPT for field formatting on primitive types.
     
    red floyd, Nov 17, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Tiger
    Replies:
    10
    Views:
    5,669
  2. ai@work
    Replies:
    9
    Views:
    570
    Ron Natalie
    Dec 16, 2004
  3. S. Nurbe

    iostream + iostream.h

    S. Nurbe, Jan 14, 2005, in forum: C++
    Replies:
    7
    Views:
    806
    red floyd
    Jan 15, 2005
  4. red floyd
    Replies:
    3
    Views:
    559
    Dietmar Kuehl
    Mar 8, 2005
  5. Kosio

    Floats to chars and chars to floats

    Kosio, Sep 16, 2005, in forum: C Programming
    Replies:
    44
    Views:
    1,347
    Tim Rentsch
    Sep 23, 2005
Loading...

Share This Page